// EZTWAIN.H - Easy interface to TWAIN library
// Copyright (C) 1999-2010 by Dosadi.
//
// This interface and the library which implements it, are the property of
// Dosadi and are protected by US and International copyright and trademark
// laws and treaties.  Dosadi strives to make this software both reliable,
// comprehensive, efficient, and affordable.  Do not use this software without
// obtaining a license for your use.
// 
// Sales, support and licensing information at: www.dosadi.com
//

#ifndef EZTWAIN_H
#define EZTWAIN_H

#ifndef _XDEFS_

#ifndef _WINDOWS_
#include "windows.h"
#endif

#ifndef __wtypes_h__
#include "wtypes.h"     // for BSTR
#endif

#ifdef __cplusplus
extern "C" {            // Assume C declarations for C++
#endif	// __cplusplus

#ifndef EZTAPI
  #ifdef _WIN32
    #define EZTAPI WINAPI
  #else
    #define EZTAPI FAR PASCAL
  #endif
#endif


typedef HANDLE HDIB;
typedef DWORD HCONTAINER;
typedef HANDLE HDOC;


#endif // _XDEFS_

HDIB EZTAPI TWAIN_Testing123(LPCSTR pz, int n, HDIB h, double d, unsigned u);
// Displays a dialog box showing the parameter values received by the function.
// Pass in any valid values for the parameters - if they are faithfully
// displayed in the dialog box when you call this function, then parameter
// passing from your program to EZTwain is probably working correctly.
//
// Returns the value of the HDIB h parameter.

//--------- Top-Level Calls

void EZTAPI TWAIN_ResetAll(void);
// Resets EZTwain to default/just loaded state.
// (Except diagnostic logging, which is unaffected.)
// Any global settings are reset to initial values.
// Any open files are closed.
// Any open TWAIN device is closed.
// This function is used to place EZTwain in a 'known state'
// before starting a sequence of scanning calls.

HDIB EZTAPI TWAIN_Acquire(HWND hwndApp);
// Acquires a single image, from the currently selected Data Source.
//
// The parameter is a Win32 Window Handle.  In most applications you
// can use 0 or NULL, but on Citrix and WTS, this must be a top-level window
// or a child of a top level window.
//
// The return value is a handle to global memory containing a DIB - 
// a Device-Independent Bitmap.  Numerous EZTWAIN DIB_xxx functions can
// be used to examine, modify, and save these DIB images.
// Warning: Remember to call DIB_Free on each DIB when you are done with it!
//
// Normally only one image is acquired per call: All Acquire functions shut
// down TWAIN before returning.  Use TWAIN_SetMultiTransfer to change this.
//
// By default, the default data source (DS) is opened, displays its dialog,
// and determines all the parameters of the acquisition and transfer.
// If you want to (try to) hide the DS dialog, see TWAIN_SetHideUI.
// To set acquisition parameters, you need to do something like this:
//     TWAIN_OpenDefaultSource() -or- TWAIN_OpenSource(sourceName)
//     TWAIN_Set*        - one or more capability-setting functions
//     hdib = TWAIN_Acquire(hwnd)
//     if (hdib) then ... process image, TWAIN_FreeNative(hdib); end

BOOL EZTAPI TWAIN_SelectImageSource(HWND hwnd);
// Display the standard TWAIN "Select Source" dialog which
// allows the user to specify the system-wide default TWAIN device.
//
// Note this is a configuration function, it does not open or activate the device.
// See: TWAIN_GetDefaultSourceName and TWAIN_OpenDefaultSource.
//
// Note: If only one TWAIN device is installed on a system, TWAIN selects it
// automatically, so there is no need for the user to do Select Source.
// You should not require your users to do Select Source before Acquire.
//
// It returns after the user either OK's or CANCEL's the dialog.
// A return of TRUE(1) indicates OK, FALSE(0) indicates one of the following:
//   a) The user cancelled the dialog
//   b) The Source Manager found no data sources installed
//   c) There was a failure before the Select Source dialog could be posted
//
// Note: You can call (Get)DefaultSourceName to get the name of the
// current default source, after calling SelectImageSource, or any other time.

int EZTAPI TWAIN_AcquireToFilename(HWND hwndApp, LPCSTR pzFileName);
// Acquire an image and save it to a file.
// If the filename is NULL or an empty string, the user is prompted for
// the file name using a standard Save File dialog.
//
// The minimal use of EZTwain is to call this function with both arguments NULL (0).
//
// If the filename passed as a parameter or entered by the user contains a
// standard extension (.bmp, .jpg/.jpeg, .tif/.tiff, .png, .pdf, .gif, .dcx)
// then the file is saved in the implied format.
// Otherwise the file is saved in the current SaveFormat - see TWAIN_SetSaveFormat.

// See also TWAIN_AcquireFile below.
//
// Return values:
//   0  success.
//  -1  the Acquire failed.
//  -2  file open error (invalid path or name, or access denied)
//  -3  invalid DIB, or image incompatible with file format, or...
//  -4  writing failed, possibly output device is full.
// -10  user cancelled File Save dialog


int EZTAPI TWAIN_AcquireMultipageFile(HWND hwndApp, LPCSTR pzFileName);
// Acquire (scan) all available images to a multipage file.
// If the filename is NULL or points to the null string, the user is
// prompted for the filename.
// If the filename ends with ".tif", ".tiff", or
// ".mpt" the file is written in TIFF format.
// If the filename ends with ".pdf" the file is written in PDF format.
// Otherwise, the default multipage format is used, as set by SetMultipageFormat.
// If it has not been set, the default multipage format is TIFF.
//
// If scanning fails or is cancelled before the first writable page
// is received, no file action is taken: The output filename is not prompted for,
// the file is not created, if it exists it is not touched.
//
// The function TWAIN_MultipageCount can be called during or after
// writing a multipage file, it reports the number of images written to the file.
// See also TWAIN_AcquireCount and TWAIN_BlankDiscardCount for other info.
//
// Return values:
//   0  success
//  -1  the Acquire failed, or the device closed or quit after 0 pages.
//      If 0 pages were written but no other error was diagnosed,
//      TWAIN_LastErrorCode will be EZTEC_0_PAGES.
//  -2  file open error (invalid path or name, or access denied)
//  -3  could not load file-format module (EZTiff.dll or EZPdf.dll)
//      Either the DLL was not found, or the version is out-of-date,
//      For PDF output, EZJpeg.dll is also required.
//      Less likely: The device returned an invalid DIB handle, or
//      the transferred image has a bit depth of 9..15 bits per pixel (??)
//  -4  writing failed, possibly output device is full.
//  -7  Multipage support is not installed.
// -10  user cancelled - This can be during the filename prompt, if you
//      did not supply a filename, or it can be when the scanner dialog
//      is first displayed.  If the scanner dialog is visible, the user
//      can cancel during a scan and the dialog will just stay open (usually)
//      allowing another try.  If the user closed the scan dialog without
//      scanning, TWAIN_LastErrorCode will be EZTEC_USER_CANCEL.
//
// This function respects TWAIN_SetHideUI as follows:
// If SetHideUI(1), then the device UI is hidden, AcquireMultipageFile
// will transfer images until the device indicates that it has no
// more images ready.  (Technically, it goes to State 5).
// Exception: If a device seems to be one-image-at-a-time (such as a flatbed)
// the user will be asked if they want to acquire another image.
//
// If SetHideUI(0) [the default case] then the device UI is shown,
// and AcquireMultipageFile will transfer images until the user
// closes the device dialog.  (You can call SetStopOnEmpty to have
// scanning stop when the device runs out of images/paper.)
//
// This function respects SetMultiTransfer() as follows:
// If SetMultiTransfer(1), the DS is left open on return.
// Otherwise (the default case), the DS is closed and TWAIN is unloaded.
//
// If you want to set scanning parameters (resolution, pixeltype...)
// first open the source (see OpenDefaultSource or OpenSource)
// then negotiate the settings using the Capability functions, and
// then call AcquireMultipageFile.
//
// Caution: It is not recommended to use this function on webcams
// if the UI is hidden.  Some will crash, others may supply images
// endlessly (until disk full.)

int EZTAPI TWAIN_AcquireToArray(HWND hwnd, HDIB ahdib[], int nMax);
// Scan and store images in the specified array.
// Very similar to TWAIN_AcquireMultipageFile.
// A return value of N > 0 means N images were scanned and stored
// without error.
// If no (0) images were scanned and stored and there was no other error,
// the return value will be -1 and TWAIN_LastErrorCode will be EZTEC_0_PAGES.
// Any unused entries in the array are set to 0 (NULL)
// In case of error, no images are returned - the scan must be restarted.

int EZTAPI TWAIN_AcquireImagesToFiles(HWND hwndApp, LPCSTR pzFileName);
// Similar to TWAIN_AcquireMultipageFile above, but writes each
// image to a separate file.  The format of the output files is
// determined by the extension of the filename, as with AcquireToFilename.
//
// If the filename is NULL or points to the null string, the user is
// prompted for the name of the first file.
//
// Files after the first are given names 'incremented' from the name
// of the first file according to this pattern:
// document.pdf increments to document1.pdf
// document99.pdf increments to document100.pdf
// document0001.tif increments to document0002.tif.
//
// Return values:
// IMPORTANT: If successful, returns the number of files written.
// Note that this could be 0 if the scanner dialog is displayed and
// the user closes the dialog without any scans.
// Otherwise, return value same as TWAIN_AcquireMultipageFile, and
// details available from TWAIN_LastErrorCode & related functions.
// 
// See also: TWAIN_AcquiredFileCount
//           TWAIN_AcquireCount
//           TWAIN_BlankDiscardCount.

int EZTAPI TWAIN_AcquirePagesToFiles(HWND hwnd, int nPPF, LPCSTR pzFile);
// Similar to AcquireImagesToFiles, but can acquire duplex or multipage files.
//
// hwnd     = parent window. Use 0 (NULL) if you can't obtain the window handle.
//
// nPPF     = *pages* per file.
//            If the scanner is scanning duplex, 1 page = 2 images
//            otherwise 1 page = 1 image.
//
// pzFile   = filename.  We recommend including the extension to specify the format.
//            If the filename is NULL or points to the empty string, the user is
//            prompted for the name of the first file.
//
// Return: If successful, returns the number of files written.
// Otherwise, same as TWAIN_AcquireMultipageFile, with
// details available from TWAIN_LastErrorCode & related functions.

int EZTAPI TWAIN_AcquireMultipage(HWND hwnd);
// Similar to AcquireToArray and AcquireMultipageFile, but does nothing
// with the images except pass them to the callback function 
// (which you should set with SetAcquireImageCallback.)
//
// Return: 0 if successful,
// Otherwise a negative number: see AcquireMultipageFile.
//
// Details of Operation:
// If the callback returns a valid DIB handle, the returned DIB is
// freed with DIB_Free.
// Otherwise the callback's return value is ignored.
// In either case, scanning continues.
// To abort scanning the callback can call TWAIN_RecordError with an error.
// Two error codes are treated specially:
// EZTEC_NONE, which is ignored and has no effect on scanning, and
// EZTEC_USER_CANCEL which causes AcquireMultipage to abort the scan
// and return a value of -1, *after clearing* the error with TWAIN_ClearError.
// All other errors cause AcquireMultipage to abort the scan and
// return -1, leaving the error code available via TWAIN_LastErrorCode & co.
//
// This function allows EZTwain to handle the complexities of multipage
// scanning while your callback function does whatever you want done with
// each image.

int EZTAPI TWAIN_AcquiredFileCount(void);
// Returns the number of files successfully written by the last call to
// AcquireImagesToFiles or AcquirePagesToFiles.

HANDLE EZTAPI TWAIN_AcquireCompressed(HWND hwndApp);
// Acquire the next available image from the open (or default) device,
// accepting a compressed memory transfer if one is selected.
// (Use TWAIN_SetCompression to select the compression algorithm.)
// 
// The DIB handle which is returned will normally reference a compressed
// DIB, which is acceptable to relatively few EZTwain functions.
// See also: DIB_IsCompressed
//
// Recommended use of this function:
// Open a device with TWAIN_OpenSource or TWAIN_OpenDefaultSource.
// Set any other scanning parameters such as PixelType, resolution, etc.
// Select memory transfer mode, using TWAIN_SetXferMech.
// Select a compression algorithm, using TWAIN_SetCompression.
// Call this function (possibly in a loop) to acquire images.


int EZTAPI TWAIN_AcquireCount(void);
// Returns the number of images acquired by the last call to
// TWAIN_AcquireMultipageFile, TWAIN_AcquireImagesToFiles,
// or TWAIN_AcquirePagesToFiles.
//
// This includes only "keeper" pages - it *excludes*
// any discarded blank pages, separator pages, etc.
//
// Therefore it may differ from the value of TWAIN_MultipageCount.

BOOL EZTAPI TWAIN_PromptToContinue(HWND hwnd);
// Prompt the user "Continue scanning?"
// Return TRUE(1) if yes, FALSE(0) if not.
// If the parameter is a valid Windows window-handle, that window
// is used as the parent of the prompt message box, otherwise
// the foreground window of the current task/process is used.
//
// The prompt is automatically translated based on thread locale
// (which defaults to application locale, which defaults to user locale,
//  which defaults to system locale)
// Languages: Danish, Dutch, English, French, German, Italian,
// Norwegian, Polish, Portuguese, Spanish, Swedish.
// Also Russian and Japanese, but those may not work....

int EZTAPI TWAIN_SetDefaultScanAnotherPagePrompt(int fYes);
// Controls an aspect of TWAIN_AcquireMultipageFile - When used
// with a non-feeder device, with UI suppressed, that function
// asks the user if they want to scan another page, [Yes] or [No].
// This function controls which answer is the default:
// fYes = 1         [Yes] is the default button/answer*
// fYes = 0         [No] is the default button/answer.
//
// * EZTwain initial setting.
//  
// Return value: Previous value of the setting.

#if !defined(_XDEFS_) || defined(DELPHI)
// Acquire callback/notification
// Don't even try to support callbacks in other languages!

typedef HANDLE (WINAPI *ACQUIREIMAGEFUNC)(HANDLE hdib, LPVOID data);

void EZTAPI TWAIN_SetAcquireImageCallback(ACQUIREIMAGEFUNC callback, LPVOID data);
// Set a 'monitor' on acquired images.
// For each image that is scanned (and not discarded), the callback function
// is called with the image handle and the 'data' value that was passed
// to SetAcquireImageCallback.
// The callback must return an image handle, there are 3 cases:
//
// 1. It can return NULL (0). This tells the main scanning function to forget
// about the image but continue scanning. The callback owns the original image and
// must see to its eventual disposal e.g. with DIB_Free.
//
// 2. It can return the same image handle it was given.
// In this case, the main scanning function takes ownership of the image back and
// processes the image in the usual way.  (The callback must *not* free the image.)
//
// 3. It can return a different image handle.
// In this case, the main scanning function continues in the usual way with
// the new image replacing the original. The callback owns the original image
// and must see to its eventual disposal e.g. with DIB_Free.
//
// Independently, the callback can record an error by calling TWAIN_RecordError

#endif

int EZTAPI TWAIN_DoSettingsDialog(HWND hwnd);
// Run the device's settings dialog, if this is supported, and return
// when the user closes the dialog.  See return codes below.
// 
// The purpose of this feature, which is definitely not supported by all
// devices, is to allow a human operator to define a complete device
// configuration, including settings that are proprietary and that may
// appear only in the device's UI.  This configuration can then be saved
// exactly and in toto, using the (TWAIN_)GetCustomData
//
// If a device is open, work with that device.  If no device is currently
// open, work with the default device.  (See GetDefaultSourceName)
// This is an *optional* TWAIN feature - To check if a device supports this,
// open the device and call TWAIN_GetCapBool(CAP_ENABLEDSUIONLY, FALSE) -
// if that call returns TRUE(1) then this feature is supported.
// Return values:
//    1     dialog was displayed and user clicked OK
//    0     dialog was displayed and user clicked Cancel
//   -1     dialog not displayed - some error.  Call LastErrorCode,
//          ReportLastError, or similar function for more details.

BOOL EZTAPI TWAIN_EnableSourceUiOnly(HWND hwnd);
// The underlying 'asynchronous' function for TWAIN_DoSettingsDialog.
// Opens the device's settings dialog, if this is supported.
// Returns TRUE (1) if successful, FALSE (0) otherwise.
// NOTE: If successful, this call leaves the dialog open, so your
// program must run a message pump at least until the user closes it.
// If you don't understand what that means, don't call this guy.

//--------- Global Options

void EZTAPI TWAIN_SetMultiTransfer(BOOL bYes);
BOOL EZTAPI TWAIN_GetMultiTransfer(void);
// This function controls the 'multiple transfers' flag.
// By default, this feature is set to FALSE (0).
//
// If this flag is zero, the input device is closed when
// any TWAIN_AcquireXXX function finishes.
//
// If this flag is non-zero: After an Acquire, the input device
// is not closed, but is left open to allow additional images
// to be acquired.  In this case the programmer should
// close the input device after all images have been
// transferred, by calling either
//     TWAIN_CloseSource or
//     TWAIN_UnloadSourceManager
//
// See also: TWAIN_UserClosedSource()

void EZTAPI TWAIN_SetHideUI(BOOL bHide);
BOOL EZTAPI TWAIN_GetHideUI(void);
// These functions control the 'hide source user interface' flag.
// This flag is cleared initially, but if you set it non-zero, then when
// a device is enabled it will be asked to hide its user interface.
// Note that this is only a request - some devices will ignore it!
// This affects AcquireNative, AcquireToClipboard, and EnableSource.
// If the user interface is hidden, you will probably want to set at least
// some of the basic acquisition parameters yourself - see
// SetUnits, SetPixelType, SetBitDepth and SetResolution below.
// See also: HasControllableUI

void EZTAPI TWAIN_SetStopOnEmpty(BOOL bYes);
BOOL EZTAPI TWAIN_GetStopOnEmpty(void);
// These functions manage the 'Stop On Empty' flag.
// This flag is off (FALSE) by default.
// When set, multipage scanning functions stop scanning and return
// when the device indicates that no more images are 'pending',
// *even if* the scanner's dialog is being displayed.
// Note that the normal behavior when the scanner dialog is displayed
// is to continue scanning until the user closes the dialog.
// Of course, behavior varies from scanner to scanner, but with most
// ADF scanners, setting Stop On Empty will cause multipage
// scanning to stop when everything in the feeder has been scanned.

void EZTAPI TWAIN_DisableParent(BOOL bYes);
BOOL EZTAPI TWAIN_GetDisableParent(void);
// Set or get the "DisableParent" flag.
// When this flag is set (non-zero), EZTwain attempts to
// disable the parent window during any Acquire function.
// (The parent window is the window you pass to the Acquire function.
// Typically this is your main application window or dialog.)
// This flag is TRUE (1) by default.
//
// Note 1: If you set this to FALSE, your window can receive user input while
// an Acquire is in progress, and your code must be prepared for this.
// Note 2: Some TWAIN data sources will disable the parent window on their
// own, and EZTWAIN cannot prevent this.


//--------- Basic TWAIN Inquiries

int EZTAPI TWAIN_EasyVersion(void);
// Returns the version number of EZTWAIN.DLL, multiplied by 100.
// So e.g. version 2.01 will return 201 from this call.
int EZTAPI TWAIN_EasyBuild(void);
// Returns the build number within the version.

BOOL EZTAPI TWAIN_IsAvailable(void);
// Call this function any time to find out if TWAIN is installed on the
// system.  It takes a little time on the first call, after that it's fast,
// just testing a flag.  It returns 1 if the TWAIN Source Manager is
// installed & can be loaded, 0 otherwise. 

BOOL EZTAPI TWAIN_IsMultipageAvailable(void);
// Return TRUE (1) if EZTwain 'multipage' services are installed.
// This allows writing of multipage TIFF (if TIFF is available)
// and multipage PDF (if PDF is available).
// It also enables TWAIN_AcquireMultipageFile

int EZTAPI TWAIN_State(void);
// Returns the TWAIN Protocol State per the spec.
#define TWAIN_PRESESSION		1	// source manager not loaded
#define TWAIN_SM_LOADED			2	// source manager loaded
#define TWAIN_SM_OPEN			3	// source manager open
#define TWAIN_SOURCE_OPEN		4	// source open but not enabled
#define TWAIN_SOURCE_ENABLED	5	// source enabled to acquire
#define TWAIN_TRANSFER_READY	6	// image ready to transfer
#define TWAIN_TRANSFERRING		7	// image in transit

BOOL EZTAPI TWAIN_IsDone(void);
// Return FALSE(0) if there is a device open and it is in a state
// where more scans are available or could be requested.
// Otherwise returns TRUE (1).
//
// Informally, TRUE means 'stop asking for images' and
// FALSE means something like 'It would be appropriate
// at this time to request another image.'
//
// Yes, it sounds bizarre, but that's actually
// how TWAIN works.
//
// This call can be used for multipage scanning
// as the test at the *bottom* of a do-until loop:
//   If TWAIN_OpenDefaultSource() Then
//      TWAIN_SetMultiTransfer(1)
//      Do
//         TWAIN_AcquireToFilename(0, NextFileName())
//      Until TWAIN_IsDone()
//      TWAIN_CloseSource()
//   End If
//

LPCSTR EZTAPI TWAIN_SourceName(void);
// Returns a pointer to the name of the currently open source, if any, or
// the name of the source that was just closed.
// Should be used while a source is open, or right after a
// source has been used and then closed.

void EZTAPI TWAIN_GetSourceName(LPSTR pzName);
// Like TWAIN_SourceName, but copies current/last source name into its parameter.
// The parameter is a string variable (char array in C/C++).
// You are responsible for allocating room for 33 8-bit characters
// in the string variable before calling this function.

//--------- DIB handling utilities ---------

BOOL	 EZTAPI DIB_IsValid(HDIB hdib);
// Returns TRUE(1) if parameter seems to be a valid DIB, FALSE(0) otherwise.
// A true return is not a guarantee, but a false return means something is
// seriously wrong.

int      EZTAPI DIB_Depth(HDIB hdib);
int      EZTAPI DIB_BitsPerPixel(HDIB hdib);
// 'depth' of image - number of bits used to store one pixel

int		 EZTAPI DIB_PixelType(HDIB hdib);
// TWAIN PixelType that describes this DIB: TWPT_BW, TWPT_GRAY, TWPT_RGB,
// TWPT_PALETTE, TWPT_CMYK, TWPT_CMY, etc.

int      EZTAPI DIB_Width(HDIB hdib);
// Width of DIB, in pixels (columns)
int      EZTAPI DIB_Height(HDIB hdib);
// Height of DIB, in lines (rows)

void     EZTAPI DIB_SetResolution(HDIB hdib, double xdpi, double ydpi);
void     EZTAPI DIB_SetResolutionInt(HDIB hdib, int xdpi, int ydpi);
// Sets the horizontal and vertical resolution of the DIB.

double   EZTAPI DIB_XResolution(HDIB hdib);
// Horizontal (x) resolution of DIB, in DPI (dots per inch)
double   EZTAPI DIB_YResolution(HDIB hdib);
// Vertical (y) resolution of DIB, in DPI (dots per inch)

int   EZTAPI DIB_XResolutionInt(HDIB hdib);
int   EZTAPI DIB_YResolutionInt(HDIB hdib);
// Return the nearest integer value to the x or y resolution of an image.

// Physical or 'implied' image size
double EZTAPI DIB_PhysicalWidth(HDIB hdib, int nUnits);
double EZTAPI DIB_PhysicalHeight(HDIB hdib, int nUnits);
// Return the width(height), in the specified units, of the given
// image, calculated using its pixel width(height) and X(Y) resolution.
// If the resolution is 0, these functions return 0.
// nUnits is one of the TWUN_ values - see TWAIN_GetCurrentUnits.
// nUnits=0 is inches, and nUnits=1 is centimeters(cm).

long     EZTAPI DIB_RowBytes(HDIB hdib);
// Number of bytes needed to store one row of the DIB.

int      EZTAPI DIB_ColorCount(HDIB hdib);
// Number of colors in color table of DIB.
// Primarily useful for B&W, gray, and palette images.
// 16-bit gray, RGB, CMY & CMYK images have no color table: DIB_ColorCount returns 0

int      EZTAPI DIB_SamplesPerPixel(HDIB hdib);
// Number of 'samples' or components or color channels in each pixel.
// B&W and gray pixels have 1 sample, RGB and CMY have 3.
// CMYK has 4, and palette-color images are treated as having 3 channels.

int      EZTAPI DIB_BitsPerSample(HDIB hdib);
// Number of bits per 'channel'.  For B&W and gray images this is
// the same as the DIB_Depth, because those formats have only one channel.
// For palette images, this will be 8, because the color values in a
// palette image are stored with 8 bits each for R, G, and B.
// For RGB, CMY, and CMYK images, this function returns the number of bits
// used to represent each color channel or component - almost always 8, but
// EZTwain has a limited ability to handle 16-bit per channel images.

BOOL	EZTAPI DIB_IsCompressed(HDIB hdib);
// Return 1(True) if image is compressed in memory 0(False) otherwise.

int		EZTAPI DIB_Compression(HDIB hdib);
// Return the TWCP_xxx code representing the compression algorithm
// of this image.  Uncompressed images yield TWCP_NONE.


#ifndef _XDEFS_

BITMAPINFOHEADER* EZTAPI DIB_Lock(HDIB hdib);
// Lock the given DIB handle and return a pointer to the header structure.
// Technically, increments the lock count of hdib and returns its address.
void     EZTAPI DIB_Unlock(HDIB hdib);
// Unlock the given DIB handle (decrement the lock count.)
// When the number of Unlocks = the number of Locks, any pointers
// into the DIB should be presumed invalid.

#endif

int EZTAPI DIB_Size(HDIB hdib);
// Return the size in memory of the given DIB.

void EZTAPI DIB_ReadData(HDIB hdib, BYTE* pdata, int nbMax);
// Read up to nbMax bytes from the given DIB into the given buffer.
// The data is read 'verbatim' from the first byte of the DIB.
// To read pixel data, see DIB_ReadRowxxx below.

void EZTAPI DIB_ReadRow(HDIB hdib, int r, BYTE* prow);
void EZTAPI DIB_ReadRowRGB(HDIB hdib, int r, BYTE* prow);
void EZTAPI DIB_ReadRowGray(HDIB hdib, int r, BYTE* prow);
void EZTAPI DIB_ReadRowChannel(HDIB hdib, int r, BYTE* prow, int nChannel);
void EZTAPI DIB_ReadRowSample(HDIB hdib, int r, BYTE* prow, int nSample);
// Read row r of the given DIB into buffer at prow.
// Caller is responsible for ensuring buffer is large enough.
// ReadRowRGB always reads 3 bytes (24 bits) for each pixel,
// ReadRowGray and ReadRowChannel always read 1 byte (8 bits) per pixel.
// Row 0 is the *top* row of the image, as it would be displayed.
// The first variant reads the data exactly as-is from the DIB, including
// BGR pixels from 24-bit DIBs, 16-bit grayscale, 1-bit B&W, etc.
// The RGB variant unpacks every DIB pixel into 3-byte RGB pixels.
// The Gray variant converts every pixel to its 8-bit gray value.
// Channel codes are: 0=Gray(Luminance), 1=Red, 2=Green, 3=Blue.  See
// 'Component codes' below.
// Samples are the bytes of the pixel: A grayscale pixel has sample 0,
// an RGB image has samples 0, 1 and 2 (which are actually Green, Red and Blue).

void EZTAPI DIB_ReadPixelRGB(HDIB hdib, int x, int y, BYTE* buffer);
void EZTAPI DIB_ReadPixelGray(HDIB hdib, int x, int y, BYTE* buffer);
void EZTAPI DIB_ReadPixelChannel(HDIB hdib, int x, int y, BYTE* buffer, int nChannel);
// Read the value of the pixel at column x row y of the DIB into the buffer.
// RGB form reads 3 bytes R,G,B
// Gray form reads 1 byte of 'equivalent gray'
// Channel form reads 1 byte of channel/component, see COMPONENT_xxx codes.


void     EZTAPI DIB_WriteRow(HDIB hdib, int r, const BYTE* pdata);
// Write data from buffer into row r of the given DIB.
// Caller is responsible for ensuring buffer and row exist, etc.

void     EZTAPI DIB_WriteRowChannel(HDIB hdib, int r, const BYTE* pdata, int nChannel);
// Write data from buffer into one color channel of row r of the given DIB.
// This function should only be used on 24-bit RGB, 32-bit RGBA, 24-bit CMY,
// 32-bit CMYK, or 8-bit grayscale images.  Its behavior on any other image is undefined.
// Channels are: 0=gray, 1=Red, 2=Green, 3=Blue, 4=Alpha or
// 1=C, 2=M, 3=Y, 4=K.

void EZTAPI DIB_WriteRowSample(HANDLE hdib, int r, const BYTE* psrc, int nSample);
// Write row of data into one sample of an image.
// Only handles 8-bit data and images with 1 or more samples of 8 bits each.
// Channels are somewhat logical properties of an image, samples are
// just the bytes in a pixel - sample 0 is byte 0, sample 1 is byte 1, etc.

// Safe versions of ReadRow and WriteRow, handy for .NET languages
void EZTAPI DIB_WriteRowSafe(HANDLE hdib, int r, const BYTE* pdata, int nbMax);
void EZTAPI DIB_ReadRowSafe(HANDLE hdib, int nRow, BYTE* prow, int nbMax);

HDIB   EZTAPI DIB_Allocate(int nDepth, int nWidth, int nHeight);
// Create a DIB with the given dimensions.  Resolution is set to 0.  A default
// color table is provided if depth <= 8.
// The image data is uninitialized i.e. garbage.

HDIB EZTAPI DIB_Create(int nPixelType, int nWidth, int nHeight, int nDepth);
// Create a DIB of the given pixel type and dimensions.
// If nDepth <= 0, uses the default depth for the given pixel type.
// Resolution is set to 0.
// For TWPT_GRAY images, a standard black-to-white color table is set.
// For TWPT_PALETTE images, a Windows-standard 256-entry color table is set.

void EZTAPI DIB_Free(HDIB hdib);
// Release the storage of the DIB.

void EZTAPI DIB_FreeArray(HDIB ahdib[], int n);
// Release storage for n DIBs in array.

/*  under consideration for EZTwain 3.4 or 4.0
void EZTAPI DIB_FreeAll(void);
// Free all DIB handles created by EZTwain but not yet freed.
// This is convenient at the end of a complex scanning function, if
// you are not keeping any DIB images in memory: Call this
// function and it cleans everything up.  This way you do not have to
// individually free each DIB as soon as you are done with it.
*/

long EZTAPI DIB_InUseCount(void);
// Return the number of DIBs 'outstanding' - allocated but not disposed of.
// Note that a DIB that is put on the clipboard becomes the property of the
// clipboard and is considered 'disposed of'.
// This function can be used to detect leaks in application DIB management.

HDIB EZTAPI DIB_Copy(HDIB hdib);
// Create and return a byte-for-byte copy of a DIB.

BOOL EZTAPI DIB_Equal(HDIB hdib1, HDIB hdib2);
// Return TRUE (1) if the two dibs are valid, have the same parameters,
// and are the same color pixel-for-pixel.

int EZTAPI DIB_MaxError(HDIB hdib1, HDIB hdib2);
// return the largest difference between two samples in the two images.

void     EZTAPI DIB_SetGrayColorTable(HDIB hdib);
// Fill the DIB's color table with a gray ramp - so color 0 is black, and
// the last color (largest pixel value) is white.  No effect if depth > 8.
void     EZTAPI DIB_SetColorTableRGB(HDIB hdib, int i, int R, int G, int B);
// Set the ith entry in the DIB's color table to the specified color.
// R G and B range from 0 to 255.

BOOL EZTAPI DIB_IsVanilla(HDIB hdib);
// TRUE if in this DIB, pixel value 0 means 'white'.
BOOL EZTAPI DIB_IsChocolate(HDIB hdib);
// TRUE if in this DIB, pixel value 0 means 'black'.

int EZTAPI DIB_ColorTableR(HDIB hdib, int i);
int EZTAPI DIB_ColorTableG(HDIB hdib, int i);
int EZTAPI DIB_ColorTableB(HDIB hdib, int i);
// Return the R,G, or B component of the ith color table entry of a DIB.
// If i < 0 or >= DIB_ColorCount(hdib), returns 0.

void EZTAPI DIB_FlipVertical(HDIB hdib);
// Flip (mirror) the bitmap vertically.
// Top and bottom rows are exchanged, etc.

void EZTAPI DIB_FlipHorizontal(HDIB hdib);
// Flip (mirror) the bitmap horizontally.
// Leftmost pixels become rightmost, etc.

void EZTAPI DIB_Rotate180(HDIB hdib);
// Rotate image 180 degrees

HDIB EZTAPI DIB_Rotate90(HDIB hOld, int nSteps);
// Return a copy of hOld rotated clockwise nSteps * 90 degrees.
// If nSteps is 0, the result is a copy of hOld.
// Negative values of nSteps rotate counterclockwise.
// Note that *hOld is not destroyed*

BOOL EZTAPI DIB_InPlaceRotate90(HDIB hdib, int nSteps);
// like DIB_Rotate90, but modifies the hdib.

void EZTAPI DIB_Fill(HDIB hdib, int R, int G, int B);
// Fill the DIB with the specified color

void EZTAPI DIB_FillRectWithColorAlpha(HDIB hdib, int x, int y, int w, int h, int R, int G, int B, int A);
// Fill the specified rectangle in the image with the specified color using transparency=A
// A = 0  is transparent (so the fill has no effect)
// A = 255 is opaque, 

void EZTAPI DIB_Negate(HDIB hdib);

void EZTAPI DIB_AdjustBC(HDIB hdib, int nB, int nC);
// *** BETA - new in 3.08b8 - use with caution.
// Adjust the brightness and/or contrast of the image.
// nB and nC are -1000 to 1000, with a value of 0 meaning 'no change'.
// Positive nB push all pixels toward white, negative toward black.
// Positive nC push all pixels away from mid-value, toward black and white.
// Negative nC pushes all pixels toward the mid-value.
// Works on grayscale, RGB, CMY(K) images - no effect on B&W and palette.

void EZTAPI DIB_ApplyToneMap8(HDIB hdib, const BYTE* map);
// Apply an 8-bit tone map to an image.
// For each pixel in hdib, calculate the 8-bit intensity (luminance) value of
// the pixel. Then replace the pixel's value with the nearest value
// whose intensity is map[v].

BOOL EZTAPI DIB_AutoContrast(HDIB hdib);
// Automatically adjust the values in the image to make
// the dominant light color into white, and the primary dark tone into black.

void EZTAPI DIB_Convolve(HDIB hdibDst, HDIB hdibKernel, double dNorm, int nOffset);
// Apply hdibKernel as a convolution kernel to hdibDst.
// At each pixel in hdibDst, hdibKernel is convolved with the neighborhood
// and the result is stored back into hdibDst.
// The point value of the convolution is normalized by dividing by dNorm, and
// then nOffset is added, before clipping to the pixel range of hdibDst.

void EZTAPI DIB_Correlate(HDIB hdibDst, HDIB hdibKernel);
// Similar to DIB_Convolve, but performs a correlation between hdibDst and hdibKernel,
// assuming that hdibKernel is image data (preferably grayscale), and putting
// the result into hdibDst.

void EZTAPI DIB_CrossCorrelate(HDIB hdibDst, HDIB hdibTemplate, double dScale, int nMin);
// Similar to DIB_Convolve, but performs a cross-correlation between hdibDst and hdibTemplate,
// assuming that hdibTemplate is grayscale image data, and putting
// the result into hdibDst.  In the output, a value of 255 signifies perfect correlation,
// 0 signifies perfect non-correlation (actually, a perfect opposite).
// All output values are divided by dScale.
// If nMin > 0, the correlation at each output pixel stops as soon as the value at that
// pixel is known to be <= nMin.  If you know that the values of interest are (say) > 200,
// setting a dMin of 128 can speed up the correlation greatly.

void EZTAPI DIB_HorizontalDifference(HDIB hdib);

void EZTAPI DIB_HorizontalCorrelation(HDIB hdib);
void EZTAPI DIB_VerticalCorrelation(HDIB hdib);

void EZTAPI DIB_MedianFilter(HDIB hdib, int W, int H, int nStyle);
// Apply a median filter to hdib using an W x H neighborhood.
// nStyle is currently ignored, but should be 0 for future compatibility.

void EZTAPI DIB_MeanFilter(HDIB hdib, int W, int H);
// Replace each pixel with the average of a W x H pixel neighborhood.
// We recommend you use odd value for W and H.

void EZTAPI DIB_Smooth(HDIB hdib, double sigma, double opacity);
// Apply a (gaussian) smoothing filter to the image.
// sigma is the controlling parameter of the Gaussian
// G(x,y) = exp(-(x^2+y^2) / 2*sigma^2) / (2 * pi * sigma^2)
// opacity is the fraction of the filter output that is blended
// back into the image i.e. out = in*(1-opacity) + f(in)*opacity

HDIB EZTAPI DIB_Sobel(HDIB hdib, int mode, int Thresh);
// Return the Sobel-edge filtered image.
// mode:
#define SOBEL_HORIZONTAL	0		// horizontal edges
#define SOBEL_VERTICAL		1		// vertical edges
#define SOBEL_SUM			2		// abs(horiz)+abs(vert)
#define SOBEL_MAX			3		// max(abs(horiz),abs(vert))

HDIB EZTAPI DIB_ScaledCopy(HDIB hOld, int w, int h);
// Create and return a new image - which is a copy of hOld
// but scaled (resampled) to have width w and height h.
// The input image must be of type TWPT_BW, TWPT_GRAY, or TWPT_RGB.
// If the input image is of type TWPT_BW, the returned image will be
// 8-bit grayscale.
// Otherwise the output image has the same type and depth as the input.
// *Don't forget to DIB_Free the old DIB when you are done with it.

BOOL EZTAPI DIB_Resize(HDIB hdib, int w, int h);
// Scale image to new pixel dimensions.
// The resolution (DPI) values are not changed.
// Returns TRUE(1) if successful, FALSE(0) otherwise.

HANDLE EZTAPI DIB_ScaleToGray(HDIB hdibOld, int nRatio);
// Create and return a new DIB containing the hdibOld image
// converted to grayscale and reduced in width & height by nRatio.
// Works well on B&W images.

HANDLE EZTAPI DIB_Thumbnail(HDIB hdibSource, int MaxWidth, int MaxHeight);
// Return a DIB containing a copy of hdibSource, scaled so that its width
// is no more than MaxWidth, and height is no more than MaxHeight.
// B&W images are converted to grayscale thumbnails.
// Remember to DIB_Free hdibSource and the thumbnail, when you are done with them.

HDIB EZTAPI DIB_Resample(HDIB hOld, double xdpi, double ydpi);
// Return a new image which is a copy of the old image, but resampled
// to the specified resolution.
// "Resampling" is the technical term for recomputing the pixels of
// an image, when you want to change the number of pixels in the image
// but not the physical size (like 8.5" x 11").
// If you resample from 300DPI to 100DPI, you will have 1/3 as many rows,
// 1/3 as many columns, 1/9 as many pixels - but the pixels will be
// marked in the image as being 3 times as 'wide' and 'tall' - so the
// physical size of the image stays the same.
// This is the same as DIB_ScaledCopy, just looked at in a different way.
// DIB_Resample will fail if the input image as either resolution <= 0,
// or if either xdpi or ydpi is <= 0.  It can also fail with insufficient memory.
// Remember to DIB_Free the old DIB when you are done with it.

HDIB EZTAPI DIB_RegionCopy(HDIB hOld, int leftx, int topy, int w, int h, int FillByte);
// Create and return a portion of DIB hOld.  The copied region is a rectangle
// w pixels wide, h pixels high, starting at (x, y) in the hOld image,
// where (0,0) is the upper-left corner of hOld, visually.
// Pixels that don't fit into the new DIB are discarded.
// (So this function can be used to crop an image.)
// If the new DIB is taller or wider than the old, the new
// pixels are filled with bytes = fill.  Common values for
// fill are:
//	-1 (or 255 or 0xFF) which fills with 1's producing white
//   0 which produces black fill.

HANDLE EZTAPI DIB_AutoCrop(HDIB hOld, int nOpts);
// Return a copy of its image argument, cropped to the 'actual document'
// within that image, if that can be determined by software.
// Uses RegionCopy (above).
// After this call, remember to DIB_Free(hOld) if you don't need it.

#define AUTOCROP_DARK		1	// crop off dark outside areas
#define AUTOCROP_LIGHT		2	// crop off light outside areas
#define AUTOCROP_EDGE		4	// crop at 'edges' - like lines
#define AUTOCROP_CHECK		8	// optimize for 'check-like' documents
#define AUTOCROP_CHECK_BACK	16	// optimize for the back of a check!

// note, we recommend not combining AUTOCROP_CHECK with DARK, LIGHT, or EDGE options.

BOOL EZTAPI DIB_GetCropRect(HDIB hdib, int nOptions, int *cropx, int *cropy, int *cropw, int *croph);
// Return a suggested crop rectangle to remove a dark border from the image.
// The rectangle is defined by an upper-left point and a width and height, in pixels.
// (As needed by DIB_RegionCopy above.)
// nOptions is currently unused and must be 0.
// DIB_AutoCrop uses this function to decide what to crop.
// A return of FALSE means no crop rectangle was found - generally this means
// that the image has content that extends to the edges, or has no definite borders
// of dark color.  For convenience, when this function returns FALSE it
// still returns a valid crop rectangle containing the entire image.

HANDLE EZTAPI DIB_AutoDeskew(HDIB hOld, int nOptions);
// Returns a copy of the image in hOld, possibly 'deskewed'.
// If it can be determined that the input image is consistently
// skewed (rotated by a small angle) then the returned image is rotated
// to eliminate that skew.
// The depth and pixel type of the image are not changed.
// The dimensions of the returned image may be slightly changed.
// nOptions is currently unused and must be 0 (zero).

double EZTAPI DIB_DeskewAngle(HDIB hdib);
// Compute and return the small clockwise rotation that would best
// 'deskew' the given image.  The return value is that angle
// in radians.  Only rotations in the range +-4 degrees are considered.

void EZTAPI DIB_SkewByDegrees(HDIB hdib, double dAngle);
// Skew the given image clockwise in place by the specified angle (in degrees)

HANDLE EZTAPI DIB_ConvertToPixelType(HDIB hOld, int nPT);
// Create and return a new DIB containing the hOld image converted
// to the specified pixel type.  Supported pixel types are:
// TWPT_BW, TWPT_GRAY, TWPT_RGB, TWPT_PALETTE, TWPT_CMY or TWPT_CMYK.
// When converting to black & white (TWPT_BW) the default conversion
// is simple thresholding - each pixel is converted to grayscale,
// then values 0..127 => Black, 128..255 => White.

HANDLE EZTAPI DIB_ConvertToFormat(HDIB hOld, int nPT, int nBPP);
// Create and return a new DIB containing the hOld image converted
// to the specified pixel type and bits per pixel.
// Unsupported and impossible combinations cause a NULL return.

HDIB EZTAPI DIB_SmartThreshold(HDIB hdib);
// Apply automatic, adaptive thresholding to hdib, return
// the resulting 1-bit image.  This function is optimized for
// thresholding scanned text.
// ** Remember to free the input image if you are done with it.

HDIB EZTAPI DIB_SimpleThreshold(HDIB hdib, int nT);
// Threshold hdib against nT and return the resulting 1-bit image.
// nT should be in the range 0 to 255.
// Pixels that are darker than nT become black in the output,
// pixels that are equal to or lighter than nT become white.
// ** Remember to free the input image if you are done with it.

int EZTAPI DIB_SetConversionThreshold(int nT);
int EZTAPI DIB_ConversionThreshold(void);
// Set/Get the threshold used by DIB_ConvertToPixelType above
// when converting to B&W.  The default value is 128 which means '50%'.
// Pixels lighter than 50% => white, darker => black.
// DIB_SetConversionThreshold returns the previous value of the threshold.

int EZTAPI DIB_FindAdaptiveGlobalThreshold(HDIB hdib);
// Find the adaptive threshold for input image

HDIB EZTAPI DIB_ErrorDiffuse(HDIB hdib);
// Create and return a new DIB containing the input image rendered
// to 1-bit B&W using error diffusion. The input image is not modified.

void EZTAPI DIB_SetConversionColorCount(int n);
int EZTAPI DIB_ConversionColorCount(void);
// Set/Get the number of colors that will be used in the next
// call to DIB_ConvertToPixelType or DIB_ConvertToFormat, if
// the output type is TWPT_PALETTE.

void EZTAPI DIB_SwapRedBlue(HDIB hdib);
// For 24-bit DIB only, exchange R and B components of each pixel.

HPALETTE EZTAPI DIB_CreatePalette(HDIB hdib);
// Create and return a logical palette to be used for drawing the DIB.
// For 1, 4, and 8-bit DIBs the palette contains the DIB color table.
// For 24-bit DIBs, a default halftone palette is returned.

void EZTAPI DIB_SetColorModel(HDIB hdib, int nCM);
int EZTAPI DIB_ColorModel(HDIB hdib);
#define EZT_CM_RGB          0
#define EZT_CM_GRAY         3
#define EZT_CM_CMYK         5

void EZTAPI DIB_SetColorCount(HDIB hdib, int n);

void EZTAPI DIB_Blt(HDIB hdibDst,		// DIB destination
					int dx, int dy,		// destination (x,y)
					HDIB hdibSrc,		// DIB source
					int sx, int sy,		// where to start in source
					int w, int h,		// width and height
					unsigned uRop);		// operation to apply
// Transfer pixels from hdibSrc into hdibDst, starting at
// (dx,dy) in the destination, and (sx,sy) in the source,
// and transferring w columns x h rows.
// Any pixels that fall outside the actual bounds of the source
// and destination DIBs are ignored.
// The operations available are:
#define EZT_ROP_COPY		0
#define EZT_ROP_OR			1
#define EZT_ROP_AND			2
#define EZT_ROP_XOR			3
#define EZT_ROP_ANDNOT      0x12

void EZTAPI DIB_BltMask(HDIB hdibDst,		// DIB destination
						int dx, int dy,		// destination (x,y)
						HDIB hdibSrc,		// DIB source
						int sx, int sy,		// where to start in source
						int w, int h,		// width and height
						unsigned uRop,		// operation to apply
						HDIB hdibMask);	// alpha-blend mask
// Like DIB_Blt, but hdibMask contains an 8-bit alpha mask that controls
// how hdibSrc and hdibDst pixels are blended.  hdibMask must be the
// same size as hdibSrc, and be 8-bits deep.
// NOTE: The only uRop currently supported is EZT_ROP_COPY

void EZTAPI DIB_PaintMask(HDIB hdibDst,		// DIB destination
						  int dx, int dy,	// destination (x,y)
                          int R, int G, int B,  // color to paint
                          int sx, int sy,   // source (mask) starting point
                          int w, int h,		// width and height
						  unsigned uRop,	// operation to apply
                          HDIB hdibMask);	// alpha-blend mask
// Like DIB_BltMask - but paints a solid color into the destination DIB
// using hdibMask as a mask or stencil.  The mask must be an 8-bit
// grayscale image. The each mask pixel controls how much paint is mixed
// into the corresponding destination pixel: white=100%, black=0%.
// if w == -1 or h == -1 it means "as much as possible"
// NOTE: The only uRop currently supported is EZT_ROP_COPY
// See the User Guide for details.

void EZTAPI DIB_DrawLine(HDIB hdibDst,          // DIB to draw into
                         int x1, int y1,        // starting row and column
                         int x2, int y2,        // ending row and column
                         int R, int G, int B);  // color

void EZTAPI DIB_DrawText(HDIB hdibDst,			// DIB to draw into
                         LPCSTR pzText,			// text to draw
                         int leftx, int topy,   // top-left row and column
                         int w, int h);			// width and height of text box
// Draw the text string into the DIB inside the given rectangle.
// If w or h is 0, the rectangle is extended to the bottom or right of the DIB.
// Default height is 14 pixels.  Default typeface is "Arial".
// Default color is black (R=G=B=0)
// See the following functions to override the default text settings.

// The following functions modify the default settings for DIB_DrawText:
void EZTAPI DIB_SetTextColor(int R, int G, int B);
int EZTAPI DIB_TextColor(void);
// return the current text color as a 32-bit COLORREF (0x00BBGGRR)
void EZTAPI DIB_GetTextColor(int *pR, int *pG, int *pB);
// returns the current text color as R,G,B values to its three parameters.

void EZTAPI DIB_SetTextAngle(int nDegrees);
// Set the rotation of text within the drawing rectangle, clockwise.
// NOTE: Currently only multiples of 90 degrees are supported.

void EZTAPI DIB_SetTextHeight(int nH);
// Set the text character height in pixels.
// If you want to set the text height in physical units (inches)
// multiply the physical height in inches by the DIB_YResolution.
// Note! Some files have resolution=0, which can often be treated as 72dpi

void EZTAPI DIB_SetTextFace(LPCSTR pzTypeface);
// Specify a typeface - Use a typeface that is available on the host system,
// or use a standard face such as Arial, MS San Serif, MS Serif.
// You can also specify "Courier" or "Times" as shortcuts for the classic
// fixed-width and serif fonts.
// Passing NULL or the empty string resets to the default face ("Arial")

void EZTAPI DIB_SetTextFormat(int nFlags);
// Sets text format according to the following flags.  The default
// format is normal, top, left
#define EZT_TEXT_NORMAL     0x0000
#define EZT_TEXT_BOLD       0x0001
#define EZT_TEXT_ITALIC     0x0002
#define EZT_TEXT_UNDERLINE  0x0004
#define EZT_TEXT_STRIKEOUT  0x0008
#define EZT_TEXT_BOTTOM     0x0100
#define EZT_TEXT_VCENTER    0x0200
#define EZT_TEXT_TOP        0x0000
#define EZT_TEXT_LEFT       0x0000      // align text left
#define EZT_TEXT_CENTER     0x1000      // align text center
#define EZT_TEXT_RIGHT      0x2000      // align text right
#define EZT_TEXT_WRAP       0x4000      // wrap lines that are too long

void EZTAPI DIB_SetTextBackgroundColor(int R, int G, int B, int A);
// Set the text background color, including transparency (alpha).
// RGB are color components, 0..255
// A is the alpha channel, from 0=100% transparent to 255=100% opaque.

///////////////////////////////////////////////////////////////////////
// Image viewing services

int EZTAPI DIB_View(HDIB hdib, LPCSTR pzTitle, HWND hwndParent);
// Display the given image in a window with the given title.
// hwndParent is the window handle of the parent window - if you
// use 0 (NULL) for this parameter, EZTwain uses the active window
// of the application if there is one, or no parent window.
// By default, the window contains just an [OK] button.
// The style of the window is a resizable dialog box.
// 0    = the [Cancel] button was pressed.
// 1    = the [OK] button was pressed.

BOOL EZTAPI DIB_SetViewOption(LPCSTR pzOption, LPCSTR pzValue);
// Same as TWAIN_SetViewOption.

BOOL EZTAPI DIB_SetViewImage(HDIB hdib);
// If the image viewer is open, change the displayed image to this one.

BOOL EZTAPI DIB_IsViewOpen(void);
// Return True if the image-view window is open, False otherwise.
// Note that the image viewer can be hidden, so it could be open
// and not be visible.

BOOL EZTAPI DIB_ViewClose(void);
// Close the image viewer window, if it is open.
// Only applies if the image viewer has been opened with the modeless option.
// Same as TWAIN_ViewClose.

void EZTAPI DIB_DrawOnWindow(
                 HDIB hdib,         // DIB image handle
                 HWND hwnd          // Windows native window handle
                 );
// Draw the DIB on the window.
// The image is scaled to just fit inside the window, while
// keeping the correct aspect ratio.  Any part of the window
// not covered by the image is left untouched (so it will normally
// be filled with the window's background color.)

void EZTAPI DIB_DrawToDC(HDIB hdib,     // DIB handle
                         HDC hDC,       // destination device context
                         int dx, int dy,// destination (x,y)
                         int w, int h,  // width and height
                         int sx, int sy // source (x,y) in DIB
                         );
// Draws DIB on a device context.
// You should call CreateDibPalette, select that palette
// into the DC, and do a RealizePalette(hDC) first.

///////////////////////////////////////////////////////////////////////
// Printing services

BOOL EZTAPI DIB_SpecifyPrinter(LPCSTR pzPrinterName);
// Specify the printer to be used when printing to the 'default printer'
// with the following functions.
// This does not change the user's default printer - it just tells
// EZTwain which printer to use as 'default'.
// Setting the printer name to NULL or the empty string tells EZTwain to
// use the user's default printer as its default printer.

int EZTAPI DIB_EnumeratePrinters(void);
// Return the number of available printers

LPCSTR EZTAPI DIB_PrinterName(int i);
// Return the name of the ith available printer, as found
// by a previous call to DIB_EnumeratePrinters.

BOOL EZTAPI DIB_GetPrinterName(int i, LPSTR PrinterName);
// Get the name of the ith available printer, as found by a previous
// call to DIB_EnumeratePrinters.
// You must allocate 256 characters for the printer name, and in many
// languages (especially Basic dialects) you must initialize the
// PrinterName variable with 256 spaces.

void EZTAPI DIB_SetPrintToFit(BOOL bYes);
BOOL EZTAPI DIB_GetPrintToFit(void);
// Get/Set the 'Print To Fit' flag.
// When this flag is non-zero, EZTwain reduces the size of images
// to fit within the printer page.  This only affects images that
// are too large to fit on the page.
// By default, this flag is FALSE (0)

int EZTAPI DIB_Print(HDIB hdib, LPCSTR pzJobname);
// Prompt the user with a Print Dialog, then print the DIB.
// Normally prints the DIB at 'actual size' - meaning the resolution
// values are used to convert the width and height from pixels to physical
// units (e.g. inches.)
// If the PrintToFit flag (see DIB_SetPrintToFit) is set and the image
// is larger than the printer page, the image is scaled to fit on the page.
// If the DIB has resolution values of 0, 72 DPI is assumed.
// The image is printed centered on the page.
// Return values:
//   0  success, no error
//  -2  specified printer not recognized or could not be opened
//  -3  invalid DIB handle (null, or DIB has been freed, or isn't a DIB handle)
//  -4  could not start document or start page error during printing
// -10  user cancelled a dialog (probably the Print dialog)

int EZTAPI DIB_PrintNoPrompt(HDIB hdib, LPCSTR pzJobname);
// Identical to DIB_Print, but prints on the default printer with
// default settings - the user is not prompted.


int EZTAPI TWAIN_PrintFile(LPCSTR pzFilename, LPCSTR pzJobname, BOOL bNoPrompt);
int EZTAPI DIB_PrintFile(LPCSTR pzFilename, LPCSTR pzJobname, BOOL bNoPrompt);
// Print the specified file as a print job with the specified job name.
// If the filename is null or empty, the user is prompted to select a file.
// If the jobname is null or empty, the actual filename is used as the jobname.
// If bNoPrompt is non-zero (True) the job is sent to the default printer,
// If bNoPrompt is zero (False) the user is prompted with the standard Print dialog.

// Printing - Multi-Page
//

int EZTAPI DIB_PrintArray(HDIB ahdib[], int nCount, LPCSTR pzJobname, BOOL bNoPrompt);
// Print the first nCount images in the array ahdib, under the given print-job name.
//
// If the job-name parameter is NULL or the empty string, the application title is used.
// If bNoPrompt is TRUE(non-zero), prints to the default printer without prompting the user,
// If bNoPrompt is FALSE(0) this function displays the standard print dialog.
//
// Return value is same as DIB_Print above.

void EZTAPI DIB_SetNextPrintJobPageCount(int nPages);
// If you are about to call DIB_PrintJobBegin, you can call this function
// *before* calling that one, to set the page count for the next print job.
// This allows the print dialog to enable the page-range controls, so the
// user can designate a range of pages to print.
//
// Do not call this function unless you are calling DIB_PrintJobBegin directly.
//
// A page count of 0 or less means 'unknown page count', which disables
// the page-range controls.
// If you enable print-range selection in the print dialog, EZTwain
// automatically suppresses printing of all non-selected pages.

int EZTAPI DIB_PrintJobBegin(LPCSTR pzJobname, BOOL bUseDefaultPrinter);
// Begin creating a multi-page print job.
//
// Jobname is the name of the print job.
// The jobname appears in the job-queue of the printer.
// In some environments it also appears on a job-separator
// page that is printed out ahead of each job.
// If Jobname is null or empty, the application title is used.
// (See TWAIN_SetAppTitle)
//
// If bUseDefaultPrinter is true (non-zero) the default printer
// is used, otherwise the user is prompted with a standard Print dialog.
//
// If you have called DIB_SetNextPrintJobPageCount (above) then the print
// dialog will offer the user the option of specifying a range of pages
// to print.  Otherwise that option is disabled and all pages are printed.
//
// If there is already a print job open when this function is called,
// it calls DIB_PrintJobEnd() to close that job before starting the new one.
//
// Return values:
//  0       success
// -2       could not open/access printer
// -4       printing output error
//-10       user cancelled Print dialog

int EZTAPI DIB_PrintPage(HDIB hdib);
// Add a page to the current print job.
//
// Only valid after a successful call to DIB_PrintJobBegin and
// before the matching DIB_PrintJobEnd.
//
// See DIB_Print for more details.
//  0       success
// -3       the DIB is null or invalid
// -4       printing output error
// -5       no print job is open

int EZTAPI DIB_PrintJobEnd(void);
// End the current print job and release it for printing.
// (Some environments will start printing as soon as a page is available.)
//  0       success
// -4       printing output error
// -5       no print job is open

///////////////////////////////////////////////////////////////////////
// Clipboard functions
//
BOOL EZTAPI DIB_PutOnClipboard(HDIB hdib);
// Place DIB on the clipboard (format CF_DIB)
// ** IMPORTANT ** After this call, the clipboard owns the
// DIB and you do not - do not attempt any
// further operations on the hdib handle.
// Treat this call just as you would a call to DIB_Free.
// Returns TRUE(1) for success, FALSE(0) otherwise.

BOOL EZTAPI DIB_CanGetFromClipboard(void);
// Return TRUE(1) if there is something on the clipboard that
// can be delivered as a DIB (by DIB_GetFromClipboard below.)
// Return FALSE(0) if not.

HDIB EZTAPI DIB_GetFromClipboard(void);
HDIB EZTAPI DIB_FromClipboard(void);        // alternate name
// Create and return a DIB with the contents of the clipboard.
// This is the first step of a 'paste' function for images.
// Returns NULL in case of error, or if no image on clipboard.

// Working with a DIB through a DC
//
int EZTAPI DIB_OpenInDC(HDIB hdib, HDC hdc);
void EZTAPI DIB_CloseInDC(HDIB hdib, HDC hdc);

// DIB File I/O
//
int EZTAPI DIB_WriteToFilename(HDIB hdib, LPCSTR pzFileName);
// Write image to file, using format implied by the filename extension.
//
// If the filename is NULL or points to a null string, the user is
// prompted for the filename and format with a standard Windows
// file-save dialog.
//
// If the final filename has a standard extension (.bmp, .jpg, .jpeg, .tif,
// .tiff, .png, .pdf, .gif, .dcx) then the file is saved in that format.
// Otherwise, the current SaveFormat is used - see TWAIN_SetSaveFormat.
//
// Return values:
//	 0	success
//	-1	user cancelled File Save dialog
//	-2	file open error (invalid path or name, or access denied)
//	-3	a) image is invalid (null or invalid DIB handle)
//      b) support for the save format is not configured
//      c) DIB format incompatible with save format e.g. B&W to JPEG.
//	-4	writing data failed, possibly output device is full
//  -5  other unspecified internal error

int EZTAPI DIB_WriteToBmp(HDIB hdib, LPCSTR pzFileName);
int EZTAPI DIB_WriteToBmpFile(HDIB hdib, HFILE fh);
int EZTAPI DIB_WriteToJpeg(HDIB hdib, LPCSTR pzFileName);
int EZTAPI DIB_WriteToPng(HDIB hdib, LPCSTR pzFileName);
int EZTAPI DIB_WriteToTiff(HDIB hdib, LPCSTR pzFileName);
int EZTAPI DIB_WriteToPdf(HDIB hdib, LPCSTR pzFileName);
int EZTAPI DIB_WriteToGif(HDIB hdib, LPCSTR pzFileName);
int EZTAPI DIB_WriteToDcx(HDIB hdib, LPCSTR pzFileName);
// Note: a return value of -3 indicates an invalid hdib handle, or
// 'no support for this format'.  -3 is also returned when attempting
// to write a Jpeg file from an image that is not 24-bit color or
// 8-bit grayscale.  1-bit B&W images cannot be saved as JPEG.
// 24-bit color images are 'quantized' to 8-bit color when written to GIF.
// All image types are converted to 1-bit B&W when written to DCX.
// Other internal errors will return -5, including insufficient memory.
// Check TWAIN_LastErrorCode for more details (maybe)

HDIB EZTAPI DIB_LoadFromFilename(LPCSTR pzFileName);
// Load an image from a file and return its handle.
// The file can be in any format supported by EZTwain Pro.
// If the file is multipage, normally this function loads page 0,
// but a preceding call to DIB_SelectPageToLoad changes that.
// A return of NULL(0) indicates failure, see TWAIN_LastErrorCode
// and related functions for more details.
// If the filename is an empty string (or NULL) the user is prompted
// with a standard file-open dialog.
// EZTwain should read any variant of its supported formats,
// except for PDF: We only claim to support reading images
// from PDFs if they were created by EZTwain Pro.

int EZTAPI DIB_FormatOfFile(LPCSTR pzFileName);
// Returns the EZT_FF_ code for the format of the specified file.
// A return < 0 indicates 'unrecognized format' or some error
// when opening or reading the file.

void EZTAPI DIB_SelectPageToLoad(int nPage);
// For use when loading multipage files.  Tells DIB_LoadFromFilename
// and DIB_LoadFromBuffer which page to load next, from a multipage file.
// Default is page 0 (first page in file).
// This value is reset to 0 after any call that tries to load a page.

int EZTAPI DIB_GetFilePageCount(LPCSTR pzFileName);
int EZTAPI DIB_FilePageCount(LPCSTR pzFileName);
// Return the number of pages in the specified file.
// If the file is a recognized multipage format
// (TIFF, PDF, DCX), the pages in the file are counted.
// All other recognized formats return a page count of 1.
// If the file cannot be opened, read, recognized, etc.
// this function records an error and returns -1.

HDIB EZTAPI DIB_LoadPage(LPCSTR pzFileName, int nPage);
// Short for DIB_SelectPageToLoad, DIB_LoadFromFilename.
// Load the specified page from the specified file.
// Page 0 is the first page in a file.  Multiple
// pages are only supported in TIFF, PDF and DCX files, all other file
// formats have a single page, page 0

int EZTAPI DIB_LoadArrayFromFilename(HDIB ahdib[], int nMax, const char* pzFilename);
// Load up to nMax images as DIBs into an array, reading from the specified file.
// If filename is null or the empty string, the user is prompted to select a file.
//
// If the user is prompted and cancels, this function returns -10.
// Otherwise if successful it returns the number of pages (images) loaded.
// Otherwise it returns -1 and you should call TWAIN_ReportLastError, TWAIN_LastErrorCode,etc.
//
// If this function returns < 0, the first nMax entries of the DIB array will be NULL (0).
// If returns N >= 0, the first N entries of the DIB array will
// contain handles to DIBs representing the first N images in the file.
// The remaining nMax-N entries in the DIB array will be NULL (0).
//
// Make sure you eventually call DIB_Free on all the loaded DIBs!

int EZTAPI DIB_LoadPagesFromFilename(HDIB ahdib[], int index0, int nMax, const char* pzFilename);
// Load up to nMax images from a specified file (or URL), starting at page index0.
// Remember pages are indexed from 0.
// Returns the number of images loaded - which can be 0 if there are no images
// in the file within the specified range.
// Returns -1 in case of error, call TWAIN_LastErrorCode & co. for more details.

int EZTAPI DIB_FormatOfBuffer(const BYTE* pBuffer, int nBytes);
// Assuming the buffer contains something like an image file, return
// the format implied by the leading bytes.
// nBytes = number of bytes of data in buffer.

int EZTAPI DIB_PageCountOfBuffer(const BYTE* pBuffer, int nBytes);
int EZTAPI DIB_BufferPageCount(const BYTE* pBuffer, int nBytes);
// Assuming the buffer contains something like an image file, return
// the number of pages (images technically) in it.
// nBytes = number of bytes of data in buffer.

HDIB EZTAPI DIB_LoadFromBuffer(const BYTE* pBuffer, int nBytes);
// Load an image from a buffer, presumably formatted like an image file.
// If DIB_SelectPageToLoad was called just before, the
// designated page is loaded from the buffer.
// nBytes = number of bytes of data in buffer.

HDIB EZTAPI DIB_LoadPageFromBuffer(const BYTE* pBuffer, int nBytes, int nPage);
// Load the specified page from a buffer - the buffer must contain an image
// file.  If the image format is one that can hold only one image, the page
// number is ignored.
// nBytes = number of bytes of data in buffer.

int EZTAPI DIB_LoadArrayFromBuffer(HDIB ahdib[], int nMax, const BYTE* pBuffer, int nBytes);
// Load up to nMax images as DIBs into an array, reading from a file in memory.
// pBuffer is the address of the buffer (memory block) holding the file to read.
// nBytes is the number of bytes of data in the buffer.
//
// Returns the number of images loaded if successful, otherwise
// it returns -1 and you should call TWAIN_ReportLastError, TWAIN_LastErrorCode, or similar.
//
// Make sure you eventually call DIB_Free on all the loaded DIBs.

int EZTAPI DIB_LoadFaxData(HDIB hdib, const BYTE* pBuffer, int nBytes, int nFlags);
// Load a DIB's contents from a buffer of CCITT fax-encoded data.
// pBuffer is the address of the buffer in memory.
// nBytes is the number of bytes of data in the buffer.
// nFlags are decoding options:
// Override with flags:
#define FAX_GROUP3_2D		0x020		// group3 2D
#define FAX_GROUP4			0x040		// group4 (2D always)
#define FAX_BYTE_ALIGNED	0x080		// rows (fax lines) begin on byte boundaries
#define FAX_REQUIRE_EOLS	0x100		// require EOLs
#define FAX_EXPECT_EOB		0x200		// expect end-of-block pattern
#define FAX_VANILLA			0x400		// 1's are white, 0's are black
// default is Group3 1D, chocolate, not byte-aligned, EOLs not required, EOB not expected.


int EZTAPI DIB_WriteToBuffer(HDIB hdib, int nFormat, BYTE* pBuffer, int nbMax);
// Write the image into the buffer in the format, not more than nbMax bytes.
// The return value is the actual size of the image - this may be more or less
// than nbMax.  If the return value > nbMax, it means only part of the image
// was written, and the buffer needs to be bigger.
// If pBuffer is NULL, no data is written - the function just returns the required
// buffer size in bytes.
// A return value of <= 0 indicates an error, such as
//   The image is invalid (null or invalid DIB handle)
//   The format is unrecognized, not supported, not installed, etc.
//   You can't save that image in that format e.g. B&W image to JPEG format.
//   Insufficient memory for temporary data structures (or corrupted heap)
//   Other internal failure.
// You can call TWAIN_LastErrorCode and similar functions for more details.

int EZTAPI DIB_WriteArrayToBuffer(const HDIB ahdib[], int n, int nFormat, BYTE* pBuffer, int nbMax);
// A combination of DIB_WriteArrayToFilename and DIB_WriteToBuffer.
// Writes n images to a memory buffer in the specified format.
// See DIB_WriteToBuffer above for the meaning of pBuffer and nbMax.
// Return value: See DIB_WriteToBuffer above.

#ifndef _XDEFS_
BSTR EZTAPI DIB_ArrayAsBSTR(const HDIB ahdib[], int nImages, int nFF);
// Format the n DIBs in the array ahdib into the file format nFF
// and return as a BSTR.
#endif

#if defined(VISUAL_BASIC)

Picture EZTAPI DIB_ToPicture(HDIB hdib);
// Convert a DIB into a VB Picture object.
// *** IMPORTANT: The DIB is consumed and becomes invalid ***
// The returned value can be declared as a Picture (or IPicture)
// and assigned to a Picture object or PictureBox.

HDIB EZTAPI DIB_FromPicture(Picture pic);
// Generate a DIB from a VB Picture object - the Picture object is unaffected.

#else
#ifdef __IUnknown_INTERFACE_DEFINED__

IUnknown* EZTAPI DIB_ToPicture(HDIB hdib);
HDIB EZTAPI DIB_FromPicture(IUnknown* pPic);

#endif
#endif

HBITMAP EZTAPI DIB_ToDibSection(HDIB hdib);
// Converts the given DIB into a kind of bitmap called a DibSection.
// *** IMPORTANT: The input DIB is consumed and becomes invalid ***
// A DibSection is a special kind of HBITMAP.  Many languages
// and imaging classes (such as GDI+, .NET Image, Delphi TBitmap) do
// not easily accept DIBs but readily accept a DibSection/HBITMAP.

HDIB EZTAPI DIB_FromBitmap(HBITMAP hbm, HDC hdc);
// Create a DIB with the contents of a GDI bitmap (preferably a DibSection).
// >> The input bitmap is NOT deleted - the returned DIB is a copy.
// If hdc = 0 (NULL) a default HDC is used.
// See also: DIB_ToDibSection

BOOL EZTAPI DIB_IsBlank(HDIB hdib, double dDarkness);
// Return TRUE(1) if the DIB has less than dDarkness fraction of 'dark' pixels.
// Return FALSE(0) otherwise.
// A typical value of dDarkness would be 0.02 which means 2% dark pixels.
// A page with less than 2% dark pixels is probably blank.

double EZTAPI DIB_Darkness(HDIB hdibFull);
// Returns the fraction of an image that consists of 'dark' pixels.
// These are pixels that would be black, if the image was converted
// to B&W using a smart thresholding.  See DIB_SmartThreshold.
// Used by DIB_IsBlank to decide if an image is blank.
// A return of 0.0 means none, 1.0 means all.  A typical office
// document is 0.02 (2%) to 0.32 (32%) dark pixels.

void EZTAPI DIB_GetHistogram(HDIB hdib, int nComponent, long histo[256]);
// Count the number of occurences of each value of the specified component
// in the given DIB (see component codes below).  Put the counts
// of each value (0..255) into the histo array.
// The histo array *must* be an array of 256 32-bit integers.
// Only works on B&W, grayscale, palette, and 24-bit RGB images.
// Example: If hdib contains 237 pixels with a grayscale value of 17, then
// this call will return histo[17] = 237.  Components are normalized
// into the range 0..255.
// Note: If hdib is a 1-bit B&W image, then histo will be all 0's, except
// for hist[0] (black) and hist[255] (white).
//
// Component codes:
#define COMPONENT_GRAY  0       // 0 = intensity or 'lightness' of pixel
#define COMPONENT_RED   1       // 1 = red component
#define COMPONENT_GREEN 2       // 2 = green component
#define COMPONENT_BLUE  3       // 3 = blue component
#define COMPONENT_LUMINANCE 0   // same as 'gray'
#define COMPONENT_SAT   4       // 4 = saturation (as in HSB, similar to Photoshop)
#define COMPONENT_HUE   5       // 5 = hue (as in HSB/HSV/HSL color models)

// For gray and B&W images, R, G, and B components are equal, and Hue and Sat are 0.
// Other components available upon request: support@dosadi.com


HDIB EZTAPI DIB_ComponentCopy(HDIB hdib, int nComponent);
// Extract and return one component (channel) of the given image.
// The returned image is an 8-bit grayscale image containing the
// specified channel of the input image, with the same width,
// height, and DPI.
// 
// Note: In future this function may return a 16-bit deep image
// when given a 16 bit/channel input image.

double EZTAPI DIB_Avg(HDIB hdib, int nComp);
double EZTAPI DIB_AvgRegion(HDIB hdib, int nComp, int leftx, int topy, int w, int h);
double EZTAPI DIB_AvgRow(HDIB hdib, int nComp, int rowy);
double EZTAPI DIB_AvgColumn(HDIB hdib, int nComp, int colx);
// Average the values of pixels in an image, region, row or column.
// Note that row 0 is the visually top-most row of an image.
// Averages either intensity (brightness) or individual color channels,
// or saturation.
// See component codes above, for DIB_GetHistogram.
// Regardless of image format, white = 255.0 and black = 0, even
// for 1-bit B&W or 16-bit grayscale or color images.
// DOES NOT SUPPORT: 4-bit/pixel images, CMY(K) images.

int EZTAPI DIB_GetBrightRects(HDIB hdib, int w, int h, int t, long xBlob[], long yBlob[], long wBlob[], long hBlob[], int nMax);
// Search the image for rectangular areas that are unusually bright.
//
// Return value: Number of rectangles found and returned.  Always <= nMax.
//
// Input parameters:
// w,h   are the minimum rectangle width & height, in pixels
// t     minimum average intensity value to be considered 'bright'
// nMax  maximum number of rectangles to return.
//
// Output parameters:
// xBlob array of long (32-bit int) values, receives x-coordinates of found rectangles
// yBlob ditto, for y-coordinates
// wBlob ditto, for widths of rectangles
// hBlob ditto, for heights of rectangles


HDIB EZTAPI DIB_ProjectRows(HDIB hdib, int nComp);
HDIB EZTAPI DIB_ProjectColumns(HDIB hdib, int leftx, int topy, int w, int h, int nComp);
// These functions create and return a 1 row x N column image, containing
// the average value of the rows (columns) of the input image, in the
// specified channel (component).
// If the source image is <= 8-bit/sample, the result image is 8-bit/sample.
// If the source image is 16 bit/sample, so is the result image.

int EZTAPI DIB_Posterize(HDIB hdib, int nLevels);

#ifndef _XDEFS_
// Generic neighborhood filter
// C/C++ only - Uses a callback function (and other C tricks).

typedef int NeighborhoodFilterFn(
    LPBITMAPINFOHEADER pbi,         // image being filtered
    BYTE *pbOut,                    // output row (points to first pixel)
    int n,                          // number of pixels available to process
    const BYTE **row,               // table of input rows
    int nfW, int nfH,               // neighborhood width & height
    int nSPP,                       // samples per pixel
    void *pContext);                // context, passed in with function

BOOL EZTAPI DIB_ApplyNeighborhoodFilter(
               HDIB hdib,
               int nfW, int nfH,                // neighborhood size
               NeighborhoodFilterFn *pnff,      // per-pixel function
               void *pContext);
#endif

//--- EXPERIMENTAL: The following functions may be removed or changed at any time.
HANDLE EZTAPI DIB_ForwardDCT(HANDLE hdib);

//--- OBSOLETE: The following functions are for backward compatibility only:
int EZTAPI TWAIN_WriteNativeToFilename(HDIB hdib, LPCSTR pzFileName);
HDIB EZTAPI TWAIN_LoadNativeFromFilename(LPCSTR pzFileName);
//HDIB EZTAPI TWAIN_LoadNativeFromFile(HFILE fh);
// removed - contact Dosadi if this causes problems for you.
int EZTAPI TWAIN_NegotiateXferCount(int nXfers);
int EZTAPI TWAIN_DibDepth(HDIB hdib);
int EZTAPI TWAIN_DibWidth(HDIB hdib);
int EZTAPI TWAIN_DibHeight(HDIB hdib);
int EZTAPI TWAIN_DibNumColors(HDIB hdib);
long EZTAPI TWAIN_DibRowBytes(HDIB hdib);
void EZTAPI TWAIN_DibReadRow(HDIB hdib, int nRow, BYTE* prow);
HPALETTE EZTAPI TWAIN_CreateDibPalette(HDIB hdib);
void EZTAPI TWAIN_DrawDibToDC(HDC hDC,int dx,int dy,int w,int h,HDIB hdib,int sx, int sy);

//--------- Documents
//
// The following functions provide an abstraction of a Document,
// represented by an opaque handle called an HDOC.
//
// A document is a sequence of 0 or more images. Documents can represent
// image files, or be entirely in memory, or a combination. They can be
// loaded, edited, saved, printed, and so on.
//.
// Images can be added to, deleted from, or re-ordered within a document.
// Individual images can be operated on using any of our DIB functions.
//
// Documents are modelled as containers for images, represented by DIBs.
// So for example, adding a DIB to a document does not copy the DIB, it
// places that actual image/DIB in the document.
//
// EZTwain keeps track of which DIBs are in which documents: If a DIB is
// 'freed' its destruction is deferred until no document contains it.

HDOC EZTAPI DOC_CreateEmpty(void);
// Create an empty document and return its handle.
// It has no associated file, 0 pages, and is marked unmodified.

void EZTAPI DOC_Destroy(HDOC hdoc);
// Close and destroy the document object.
// Closes any associated open file.
// Does not save changes! Use DOC_Save or related functions.

int EZTAPI DOC_ImageCount(HDOC hdoc);
// Return the number of images in the document.

BOOL EZTAPI DOC_IsModified(HDOC hdoc);
// Return TRUE if the document or any image in the document has been
// modified since the last operation that cleared the Modified flag.

void EZTAPI DOC_SetModified(HDOC hdoc, BOOL bIsMod);

LPCSTR EZTAPI DOC_Filename(HDOC hdoc);
// Return (a pointer to) the filename associated with this document.
// If there is no associated file, returns the empty string ("")

BOOL EZTAPI DOC_SetCurPos(HDOC hdoc, int i);
int EZTAPI DOC_CurPos(HDOC hdoc);
// Set/return the current position within the document.
// Intended as a way to designate an 'active' or selected page.
// The value of this property is normally >= 0 and < ImageCount, but
// can be -1 which conventionally means 'undefined' or 'no current position'.
// Operations that add, move, or remove pages may change the
// current position, see the descriptions of specific functions
// for details.

HDOC EZTAPI DOC_OpenReadOnly(LPCSTR pzFilename);
// Open an image file for read-only access.
//
// If the filename is NULL or the empty string, the user is prompted
// to select a file in a supported format.

// Returns NULL (0) if the file does not exist or cannot be opened.
//
// This function opens the designated file for shared read-only access,
// the file cannot be opened for writing as long as this document
// has it open.
//
// Important: The returned document can be freely modified, the
// modifications will not (and cannot) be saved back to the file.

HDOC EZTAPI DOC_OpenForUpdate(LPCSTR pzFilename);
// Open an image file for reading & modification.
// The designated file is opened for read/write with exclusive access:
// the file cannot be opened for reading *or* writing by anybody else.
// Changes are not written back to the file until DOC_Save is called.

void EZTAPI DOC_Reset(HDOC hdoc);
// Reset the document to empty, unmodified, no associated file.

BOOL EZTAPI DOC_WriteToFile(HDOC hdoc, LPCSTR filename);
// Write the contents of the document to the designated file.
// If the filename is NULL or the empty string, the user is prompted
// for the file (and folder) to write to.
// Does *not* clear the modified flag or associate filename with this document.
// Returns TRUE(1) if successful, FALSE(0) otherwise.

BOOL EZTAPI DOC_Save(HDOC hdoc);
// Save the contents of the document to the associated file.
// If no associated file, does a DOC_SaveAs.
// Clears the modified flag if successful.
// Returns TRUE(1) if successful, FALSE(0) otherwise.

BOOL EZTAPI DOC_SaveAs(HDOC hdoc, LPCSTR filename);

HDIB EZTAPI DOC_Image(HDOC hdoc, int i);
// Return the image at position i (0..N-1) where N=ImageCount.
// If hdoc is not valid or there is no image i (or image i cannot be read)
// then this function returns NULL.

BOOL EZTAPI DOC_SetImage(HDOC hdoc, int i, HDIB hdib);
// Set the image at position i.
// The image is *not* copied - it becomes part of the document.
// hdoc must be a valid document
// i must be >= 0 and < ImageCount(hdoc)
// hdib must be a valid DIB handle.
// Otherwise this function fails and returns FALSE(0).

BOOL EZTAPI DOC_AppendImage(HDOC hdoc, HDIB hdib);
// Such a common case of insertion it gets its own function.

HDOC EZTAPI DOC_ExtractImages(HDOC hdoc, int i, int n);
// Using the n images starting at position i in this document,
// create a new document containing *copies* of those images, in order.
// If there are less than n images at position i, uses as
// many as there are.
// The new document has no associated file and is marked unmodified(?)
 
BOOL EZTAPI DOC_DeleteImage(HDOC hdoc, int i);
// Delete the ith image in the document.
// If this document is the only document containing that image, the
// image is freed/destroyed.
// Fails if there is no image at position i.
// Returns TRUE(1) if successful, FALSE(0) otherwise.

BOOL EZTAPI DOC_DeleteImages(HDOC hdoc, int i, int n);
// delete n images starting with image i in the document.
// If there are fewer than n images starting at position i, deletes
// as many as there are.

BOOL EZTAPI DOC_InsertImage(HDOC hdoc, int i, HDIB hdib);
// Insert the image at position i in the document.
// The image is *not* copied, it becomes part of the document.
// position 0 is the first image in the document.
// position -1 is interpreted as 'at the end'.

BOOL EZTAPI DOC_InsertImageArray(HDOC hdoc, int i, HDIB ahdib[], int n);
// insert n images from array ahdib at position i

BOOL EZTAPI DOC_MoveImage(HDOC hdoc, int iOld, int iNew);
// Move the image at position iOld in the document to position iNew.
// 

//--------- File Read/Write

//---- Dosadi File Format Codes
#define EZT_FF_TIFF        0      // Tagged Image File Format
#define EZT_FF_BMP         2      // Windows Bitmap
#define EZT_FF_JFIF        4      // JPEG File Interchange Format
#define EZT_FF_PNG         7      // Portable Network Graphics
#define EZT_FF_PDFA       15      // PDF/A
#define EZT_FF_DCX        97      // CAS multipage fax format
#define EZT_FF_GIF		  98	  // Compuserve GIF89
#define EZT_FF_PDF        99      // PDF

// GIF and DCX support is only provided by EZTwain.
// Note: BMP support is built into EZTwain, so is always available.


BOOL EZTAPI TWAIN_IsJpegAvailable(void);
// Return TRUE (1) if JPEG/JFIF image files can be read and written.
// Returns 0 if JPEG support has not been installed.

BOOL EZTAPI TWAIN_IsPngAvailable(void);
// Return TRUE (1) if PNG format support is available.

BOOL EZTAPI TWAIN_IsTiffAvailable(void);
// Return TRUE (1) if TIFF format support is available.

BOOL EZTAPI TWAIN_IsPdfAvailable(void);
// Return TRUE (1) if PDF format support is available.

BOOL EZTAPI TWAIN_IsGifAvailable(void);
// Return TRUE (1) if GIF format support is available.

BOOL EZTAPI TWAIN_IsDcxAvailable(void);
// Return TRUE (1) if DCX format support is available.
// Note that DCX files can only hold 1-bit
// B&W images - EZTwain converts the image data as needed.

BOOL EZTAPI TWAIN_IsFormatAvailable(int nFF);
// Return TRUE (1) if the specified file format support
// is available for writing and possibly reading files.
// A format is considered available if EZTwain can load
// the necessary DLLs.  See the 

int EZTAPI TWAIN_FormatVersion(int nFF);
// Return the format module version * 100.

BOOL EZTAPI TWAIN_IsFileExtensionAvailable(LPCSTR pzExt);
// Return TRUE (1) if the file format corresponding to the given
// file extension ("TIF", ".gif", "jpeg", etc.) is available.
// Case does not matter, leading '.' is optional.

int EZTAPI TWAIN_FormatFromExtension(LPCSTR pzExt, int nFF);
// Return the file-format code (see File Formats above) for
// the given extension.  If pzExt is unrecognized, returns nFF.
// Case does not matter, leading '.' is optional.

LPCSTR EZTAPI TWAIN_ExtensionFromFormat(int nFF, LPCSTR pzDefExt);
// Return the default extension associated with a file format.(See File Formats above.)
// Note: The leading '.' is included e.g. ".bmp", ".tif", etc.
// If nFF is not a valid value, returns its second parameter.

void EZTAPI TWAIN_GetExtensionFromFormat(int nFF, LPCSTR pzDefExt, LPSTR szExtension);
// Return the default extension for the given file-format code, in the 3rd parameter.
// The caller is responsible for allocating a string of at least 5 characters for the 3rd parameter.
// If the file format is not recognized, returns the value of the 2nd parameter.

BOOL EZTAPI TWAIN_SetSaveFormat(int nFF);
int EZTAPI TWAIN_GetSaveFormat(void);
// Select the default file format for DIB_WriteToFilename
// and TWAIN_WriteToFilename to use, when they do not
// recognize the file extension.
// Displays a warning message if the format is not available.
// Returns TRUE (1) if ok, FALSE (0) if format is invalid or not available.
// See list of file formats above.  Some formats are not supported
// by some versions of EZTWAIN, or require external DLLs be installed.

void EZTAPI TWAIN_SetJpegQuality(int nQ);
int EZTAPI TWAIN_GetJpegQuality(void);
// Set the 'quality' of subsequently saved JPEG/JFIF image files.
// nQ = 100 is maximum quality & minimum compression.
// nQ = 75 is 'good' quality, the default.
// nQ = 1 is minimum quality & maximum compression.
 
//- Special TIFF options ------------------------------------------

void EZTAPI TWAIN_SetTiffStripSize(int nBytes);
int EZTAPI TWAIN_GetTiffStripSize(void);
// Set/Get the size of the 'strips' that TIFF files are divided into.
// Some (bogus) TIFF readers cannot handle multiple strips, to make
// them happy set the strip size to -1.
// Default value = 32768 (subject to change, in theory.)

BOOL EZTAPI TWAIN_SetTiffImageDescription(LPCSTR pzText);
BOOL EZTAPI TWAIN_SetTiffDocumentName(LPCSTR pzText);
// Set the TIFF ImageDescription or DocumentName tags for output.
// These values apply only to the next TIFF file written, and are cleared
// once the file is closed.

BOOL EZTAPI TWAIN_SetTiffCompression(int nPT, int nComp);
int EZTAPI TWAIN_GetTiffCompression(int nPT);
// Set/Get the compression mode to use when writing TIFF files.
// Set returns TRUE (1) if successful, FALSE (0) otherwise.
// nPT specifies the Pixel Type - See the TWPT_* constants.
// Different compressions apply to different pixel types - see below.
// Using nPT=-1 means 'for all applicable pixel types.'
// nComp specifies the compression, here are the codes:
#define	    TIFF_COMP_NONE		1	// no compression (all image types)
#define	    TIFF_COMP_CCITTRLE	2	// CCITT modified Huffman RLE (BW only)
#define	    TIFF_COMP_CCITTFAX3	3	// CCITT Group 3 fax encoding (BW only)
#define	    TIFF_COMP_CCITTFAX4	4	// CCITT Group 4 fax encoding (BW only)
#define     TIFF_COMP_LZW       5   // LZW compression (all image types?)
#define	    TIFF_COMP_JPEG		7	// JPEG DCT TIFF_COMP (GRAY & RGB only)
#define     TIFF_COMP_PACKBITS  32773   // generic RLE - B&W,GRAY,RGB: poor for photos

// Default for BW is TIFF_COMP_CCITTFAX4
// Default for all other pixel types is TIFF_COMP_NONE.

// Setting TIFF tags explicitly, including custom/private tags:
BOOL EZTAPI TWAIN_SetTiffTagShort(int nTagId, short sValue);
BOOL EZTAPI TWAIN_SetTiffTagLong(int nTagId, long nValue);
BOOL EZTAPI TWAIN_SetTiffTagString(int nTagId, LPCSTR pzText);
BOOL EZTAPI TWAIN_SetTiffTagDouble(int nTagId, double dValue);
BOOL EZTAPI TWAIN_SetTiffTagRational(int nTagId, double dValue);
BOOL EZTAPI TWAIN_SetTiffTagRationalArray(int nTagId, const double dValues[], int n);
BOOL EZTAPI TWAIN_SetTiffTagBytes(int nTagId, const BYTE* pdata, int nBytes);
BOOL EZTAPI TWAIN_SetTiffTagUndefined(int nTagId, const BYTE* pdata, int nBytes);
// Note: It works to use SetTiffTagDouble to set standard TIFF tags that are of
// type RATIONAL, but we recommend using SetTiffTagRational.
// If you have trouble setting a custom private tag, it may help to
// define it to EZTwain - see TWAIN_DefineCustomTiffTag, below.

void EZTAPI TWAIN_ResetTiffTags(void);
// The functions above allow specific TIFF tags to be set.
// Whatever value(s) you set will be used in *each image written to TIFF*
// until you call TWAIN_ResetTiffTags.
// Note that integer values are appropriately converted to 16- or 32-bit
// signed or unsigned as needed by the specific tag.

BOOL EZTAPI TWAIN_GetTiffTagAscii(LPCSTR pzFilename, int nPage, int nTag, int nLen, LPSTR buffer);
// Read the value of the specified tag from the given page of the given TIFF file,
// copying the string into buffer, which has room for len characters.
// Returns True(1) if successful, False(0) otherwise.

LPCSTR EZTAPI TWAIN_TiffTagAscii(LPCSTR pzFilename, int nPage, int nTag);
// Return the value of the specified tag from the given page of the given TIFF file,
// as a human-readable string.
// Numeric values are converted to decimal numeric representation.
// In case of failure, it returns the empty string.
// In case of error, call TWAIN_ReportLastError to display details,
// or call TWAIN_LastErrorCode and related functions.

void EZTAPI TWAIN_SetFileAppendFlag(BOOL bAppend);
BOOL EZTAPI TWAIN_GetFileAppendFlag(void);
// Set or get the File Append Flag.
// When this flag is non-zero and EZTwain writes to an existing TIFF, PDF or DCX
// file, the new images are *appended* to the existing file.
// When this flag is False (0), writing to any existing file replaces the file.
//
// The default state of this flag is: False (0).
//
// Note: Only TIFF, PDF, and DCX formats are affected.
// This applies to all functions that write images, primarily:
//  TWAIN_AcquireToFilename, TWAIN_AcquireMultipageFile,
//  DIB_WriteToFilename, TWAIN_BeginMultipageFile, etc.

//- PDF Specific ------------------------------------------


BOOL EZTAPI PDF_IsOneOfOurs(LPCSTR pzFileName);
// Returns TRUE(1) if the specified PDF file was probably written by the
// Dosadi PDF module.

LPCSTR EZTAPI PDF_DocumentProperty(LPCSTR pzFilename, LPCSTR pzProperty);
// From the given PDF file, extract the designated document property's string value,
// and return (a pointer to an internal buffer holding) that value.
// See also PDF_GetDocumentProperty below.
//
// Legal values for the Property parameter are:
//   "Title", "Author", "Subject", "Keywords", "Creator" and "Producer".
// Case matters, so use these exact strings.
//
// If the file cannot be opened and parsed as a PDF file, or if the specified property
// cannot be found and read, this function returns the empty string, and
// records an error: See TWAIN_ReportLastError and related functions.

int EZTAPI PDF_GetDocumentProperty(LPCSTR pzFilename, LPCSTR pzProperty, LPSTR buffer, int buflen);
// Same as PDF_DocumentProperty, except:
// The property value is obtained as a string and its length is calculated with strlen.
// The return value of this function is the 'strlen' of the string value found in the file -
// independent of the value of buflen.

// These functions configure or add information to the next output PDF file:
BOOL EZTAPI TWAIN_SetPdfTitle(LPCSTR pzText);
BOOL EZTAPI TWAIN_SetPdfAuthor(LPCSTR pzText);
BOOL EZTAPI TWAIN_SetPdfSubject(LPCSTR pzText);
BOOL EZTAPI TWAIN_SetPdfKeywords(LPCSTR pzText);
BOOL EZTAPI TWAIN_SetPdfCreator(LPCSTR pzText);

// Alternate forms of TWAIN_SetPdfTitle & co:
BOOL EZTAPI PDF_SetTitle(LPCSTR pzText);
BOOL EZTAPI PDF_SetAuthor(LPCSTR pzText);
BOOL EZTAPI PDF_SetSubject(LPCSTR pzText);
BOOL EZTAPI PDF_SetKeywords(LPCSTR pzText);
BOOL EZTAPI PDF_SetCreator(LPCSTR pzText);

BOOL EZTAPI PDF_SetCompression(int nPT, int nComp);
int EZTAPI PDF_GetCompression(int nPT);
// Select the compression algorithm to use for images with the given pixel format.
// See the TWPT_* constants for the various pixel formats.
// Note that a pixel format of -1 means 'all applicable formats'.
// Available values of nComp are:
#define		COMPRESSION_DEFAULT	-1	// reset to default. FLATE for B&W, JPEG for others.
#define	    COMPRESSION_NONE	 1	// no compression (all image types)
#define     COMPRESSION_FLATE    5	// An LZ or 'zip' compression (all image types)
#define	    COMPRESSION_JPEG	 7	// JPEG (grayscale & RGB only)

BOOL EZTAPI PDF_SelectPageSize(int nPaper);
int EZTAPI PDF_SelectedPageSize(void);
// Set/Get the standard page-size for subsequent PDF output pages.
// The values are PAPER_ values defined elsewhere
// in this file, search for PAPER_A4 etc.
// EZTwain initializes this to PAPER_NONE (0).
// With PAPER_NONE selected, EZTwain writes each output image into a
// page the same size as the image.  Setting a page size tells
// EZTwain to center each output image within a page of the
// specified size, shrinking larger images to fit.
// Calling PDF_SelectPageSize(PAPER_NONE) clears the page-size
// back to the default i.e. 'no specific size'.

BOOL EZTAPI PDF_SetPDFACompliance(int nLevel);
int EZTAPI PDF_GetPDFACompliance(void);
// Set/Get the PDF/A Compliance level.
// Level 0 is 'no particular compliance'. (*default*)
// Level 1 is PDF/A-1(b) - the PDF/A Part 1 level suitable for
// scanned documents.
// No other nLevel values are accepted at this time.
// When PDFA compliance is set to 1, PDF output is made to comply with
// ISO 19005-1 PDF/A-1.  For the most part this is invisible, but certain
// PDF settings and operations become illegal, and there are optional
// function calls that make your PDF's "more" PDF/A compliant.

#if 0
//---- Under consideration for a future release ----
void EZTAPI PDF_SetWriteSearchable(BOOL bYes);
BOOL EZTAPI PDF_GetWriteSearchable(void);
// Set/Get the global Write-Searchable-PDF option.
// When this option is set, each page written to PDF is automatically
// accompanied by invisible searchable text generated using OCR and
// written using PDF_WriteOcrText.
//
// If this implicit OCR fails for any reason, the function that requested
// it will fail.  Use TWAIN_LastErrorCode and related functions to diagnose
// and report such errors.
//
// This option is 'smart' - if other options or function calls write
// searchable text for a page, the process is not needlessly repeated.
#endif

//-- Passwords and encryption of PDF files ------------------------
//

BOOL EZTAPI PDF_IsEncrypted(LPCSTR pzFileName);
// Returns TRUE(1) if the specified PDF file is encrypted.

void EZTAPI PDF_SetOpenPassword(LPCSTR pzPassword);
// Set the password to be used to open subsequent PDF files.
// This password is used until reset to the empty string.
//
// Once you set a non-null OpenPassword, the user will not be prompted
// for a password when an encrypted PDF is opened for reading:
// If the OpenPassword is valid for the file, the file will be
// silently opened and decrypted.
// If the OpenPassword is not valid for the file, the function that
// is trying to read the file will fail. In this case,
// the code returned by TWAIN_LastErrorCode is EZTEC_PDF_PASSWORD

// To suppress PDF password prompting by EZTwain, set the OpenPassword
// to some extremely unlikely password string, such as " " or "1".

void EZTAPI PDF_SetUserPassword(LPCSTR pzPassword);
// Define a user password for the next/current output PDF file.
// This turns on encryption for the file.
// When a PDF file is completed and closed, this user password is cleared.

void EZTAPI PDF_SetOwnerPassword(LPCSTR pzPassword);
// Define an owner password for the next/current output PDF file.
// This turns on encryption for the file.
// When a PDF file is completed and closed, this owner password is cleared.

void EZTAPI PDF_SetPermissions(long nPermission);
long EZTAPI PDF_GetPermissions(void);
// Set or Get the permissions mask to be written into the next/current
// output PDF file. This mask specifies operations to be allowed or
// prevented on the file - see the PDF_PERMIT constants.
//
// Important Notes
//
// * Permissions are only written if you set a User or Owner password.
// * Acrobat honors these restrictions, but other PDF readers may not.
// * Any permissions you set only apply to the next PDF file you write.
// * The default permissions mask is 'allow everything' (-1)
// * Setting permissions=0 means 'prevent everything'
//
// You can use bitwise operations, or +/- to combine these constants.
// For example, to disallow copying text and graphics from the file:
//    PDF_SetPermissions(PDF_PERMIT_ALL - PDF_PERMIT_COPY)
//
//      named constant			value	if restricted, Acrobat will prevent:
#define PDF_PERMIT_PRINT	4		// printing the file
#define PDF_PERMIT_MODIFY	8		// making any changes, other than notes & form fields
#define PDF_PERMIT_COPY		16		// copying or extracting content
#define PDF_PERMIT_ANNOTS	32		// adding or changing comments or form fields
// You can also use this nPermission value, by itself:
#define PDF_PERMIT_ALL		-1		// restrict or allow everything


//-- Writing text into PDF. ------------------------
//
// The following functions apply to the next PDF file or page that is output,
// so you make them *before* you write the PDF page they apply to.

void EZTAPI PDF_DrawText(double leftx, double topy, LPCSTR pzText);
// Draw text into the next PDF page, x pixels from the left edge
// and y pixels down from the top of the page.
// Note 1: This is not 'native' PDF coordinates, which are
// usually in points, from the lower-left corner of the page.
// Note 2: This call only makes sense if followed at some point
// by a call that writes an image to PDF.

void EZTAPI PDF_DrawInvisibleText(double leftx, double topy, LPCSTR pzText);
// Like PDF_DrawText, but text is drawn in invisible mode.

void EZTAPI PDF_SetTextVisible(BOOL bVisible);
BOOL EZTAPI PDF_GetTextVisible(void);
// Set the visibility of the text written by subsequent PDF_DrawText
// calls. A parameter of True (non-0) means make text visible, a parameter
// of False (0) means make text invisible.

void EZTAPI PDF_SetTextSize(double dfs);
// Set the size of the current font, for subsequent PDF_DrawText calls.
// Normally this is a traditional size in points, like 10.
void EZTAPI PDF_SetTextHorizontalScaling(double dhs);

BOOL EZTAPI PDF_WriteOcrText(const char* text, const int ax[], const int ay[], const int aw[], const int ah[], double xdpi, double ydpi);
// Write previously OCR'd text to the next PDF output page.
// ---parameters---
// text is the text, of course - as returned by OCR_Text.
// ax and ay are arrays of x,y positions of the characters in text - as returned
// by OCR_GetCharPositions.  These are pixel coordinates relative to the top-left of the page.
// aw and ah are arrays of (width,height) information as returned by OCR_GetCharSizes.
// xdpi and ydpi are the resolution values (DPI) of the source image, required to map the text
// size from pixels into PDF font sizes.  The resolution can be obtained from the image
// using DIB_XResolution and DIB_YResolution, or you can call OCR_GetResolution at the
// same time you call OCR_GetCharPositions and OCR_GetCharSizes.

//---------------------------------------------------------

int EZTAPI TWAIN_WriteToFilename(HDIB hdib, LPCSTR pzFileName);
// Writes the specified image to a file.
// This is the same as DIB_WriteToFilename - please refer to that function.

HDIB EZTAPI TWAIN_LoadFromFilename(LPCSTR pzFileName);
// Load a .BMP file, or any other available format.
// Accepts a filename (including path & extension).
// If the filename is NULL or points to a null string, the user is
// prompted to choose a file with a standard File Open dialog.
// Returns a DIB handle if successful, otherwise NULL.

HDIB EZTAPI TWAIN_LoadPage(LPCSTR pzFileName, int nPage);
// Short for DIB_SelectPageToLoad, DIB_LoadFromFilename.
// Load the specified page from the specified file.
// Page 0 is the first page in a file.  Multiple
// pages are only supported in TIFF, PDF and DCX files, all other file
// formats have a single page, page #0.

int EZTAPI TWAIN_FormatOfFile(LPCSTR pzFileName);
// Return the format of the specified file.
// See the EZT_FORMAT_ codes elsewhere in this file.
// A return value < 0 means 'unrecognized format'.

int EZTAPI TWAIN_PagesInFile(LPCSTR pzFileName);
// Return the number of pages in the specified file.
// For multipage formats (TIFF, PDF, DCX), the pages are counted.
// All other recognized formats return a page count of 1.
// If the file cannot be opened, read, recognized, etc.
// this function records an error and returns -1.

BOOL EZTAPI TWAIN_PromptForOpenFilename(LPSTR pzFileName);
// Prompt the user for a file to open.
// Returns TRUE(1) if user selected a file, FALSE(0) if user cancelled.
// If it returns TRUE, the fully-qualified filepath & name is returned
// in the buffer referenced by the parameter.
// The caller is responsible for allocating (and deallocating) the
// buffer of at least 260 characters.
// The file dialog has a file-type list, which is loaded based
// on the formats that are currently supported for loading.
// The default file-type is "any supported format".

//--------- File View Dialog

int EZTAPI TWAIN_ViewFile(LPCSTR pzFileName);
// Display the specified file in a viewer window that allows the
// user to browse to all pages (if more than one).
// If the file name is NULL or the null string, the user is prompted
// with a standard file-open dialog, offering all the filetypes that
// EZTwain believes it can open.
// The default dialog has an OK button only.
// Return values:
//  1   [OK] button pressed (in modal dialog)
//  1   File displayed - in case of modeless dialog.
//  0   [Cancel] button pressed
// -1   user cancelled file-open prompt (if you supplied a null filename)
// -2   error displaying dialog, opening file, etc.

BOOL EZTAPI TWAIN_SetViewOption(LPCSTR pzOption, LPCSTR pzValue);
// Set various options and parameters for the viewer window.
// See TWAIN_ViewFile above.
//
// option			form	meaning
// title			string	the title (caption) of the viewer window
// left				x|x%	left(x) coordinate of window, in pixels or as a percent of screen.
// top				y|y%	top coordinate of window
// bottom			y|y%
// right			x|x%
// width			w|w%	width of viewer window, in pixels or as a percent of screen.
// height			h|h%
// size				w,h		width and height together, pixels or percentages
// topleft			x,y		x and y together, pixels or percentages
// position			x,y,w,h	left,top,width,height - in pixels or percentages
// pos					same as position
// pos.remember		bool	if true, remember viewer position between showings. Default: false.
// timeout			n		in seconds. Currently ignored.
// visible			bool	if viewer is open, show or hide it.  Default: true
// ok.visible		bool	if true, include an [OK] button in the viewer. Default: true.
// cancel.visible	bool	if true, include a [Cancel] button. Default: false
// print.visible	bool	if true, include a [Print] button. Default: false.
// modeless			bool	if true, leave viewer open until TWAIN_ViewClose. Default: false.
// modal			bool	opposite of modeless.
// reset			...		setting this option resets all options to default value.


BOOL EZTAPI TWAIN_IsViewOpen(void);
// Return True if the viewer window is open, False otherwise.

BOOL EZTAPI TWAIN_ViewClose(void);
// If the viewer window is open (as a modeless dialog), close it.
// The viewer window is normally modal, but can be made modeless
// with TWAIN_SetViewOption("modeless", "true")
// No effect if no viewer window is open.
// Returns True(1) if it closed the viewer window, False(0) otherwise.

BOOL EZTAPI TWAIN_GetLastViewPosition(int *pleft, int *ptop, int *pwidth, int *pheight);
// Return the screen coordinates, in pixels, of the last known position of the
// viewer window (the dialog displayed by TWAIN_ViewFile and DIB_View functions.)
// The four parameters are pointers to 32-bit integers or if your language
// prefers, four 32-bit integers passed by reference.
// The four returned values are the left edge, the top edge (counting down from screen top)
// the width, and the height of the View window, the last time it was closed or resized.
//
// This function can be used in conjunction with TWAIN_SetViewOption("position","x,y,w,h") to
// remember and restore the view window position.

//--------- Multipage File Output

#define MULTIPAGE_TIFF  0
#define MULTIPAGE_PDF   1
#define MULTIPAGE_DCX   2

int EZTAPI TWAIN_SetMultipageFormat(int nFF);
int EZTAPI TWAIN_GetMultipageFormat(void);
// Select/query the default multipage file save format.
// The default when EZTwain is loaded is MULTIPAGE_TIFF.
// Note that if you use a recognized extension in the name
// of your multipage file - such as .tif, .pdf or .dcx, then
// the file will be written in that format.  The file
// extension overrides SetMultipageFormat.
//
// SetMultipageFormat returns:
//  0 = success,
// -1 = invalid/unrecognized format
// -3 = format is currently unavailable (missing/bad DLL)

void EZTAPI TWAIN_SetLazyWriting(BOOL bYes);
BOOL EZTAPI TWAIN_GetLazyWriting(void);
// Get/Query the value of the 'LazyWriting' flag.
// NOTE: The default value of this flag is: TRUE.
// When the LazyWriting flag is set (TRUE), multipage files
// are written by a background thread, allowing your
// program to continue executing (scanning for example).
// Only when EndMultipageFile is called does the program
// wait until all the pages of the file have actually
// been written to disk.
// This also applies to AcquireMultipageFile, which internally
// uses these multipage output functions.

int EZTAPI DIB_WriteArrayToFilename(const HDIB ahdib[], int n, LPCSTR pzFileName);
// Write n images from array ahdib to the specified file.
// If n is 1, this is exactly equivalent to calling DIB_WriteToFilename.
// If n > 1, this is a shortcut for calling
//    TWAIN_BeginMultipageFile,
//      TWAIN_DibWritePage (for each image)
//    TWAIN_EndMultipageFile
// ...with appropriate error handling, of course.
//
// Return values:
//	 0	success
//	-1	user cancelled File Save dialog
//	-2	file open error (invalid path or name, or access denied)
//	-3	a) image is invalid (null or invalid DIB handle)
//      b) support for the save format is not available
//      c) DIB format incompatible with save format e.g. B&W to JPEG.
//	-4	writing data failed, possibly output device is full
//  -5  other unspecified internal error
//  -6  a multipage file is already open
//  -7  multipage support is not installed.

int EZTAPI TWAIN_BeginMultipageFile(LPCSTR pzFileName);
// Create an empty multipage file of the given name.
// If the filename is NULL or points to the null string, the user
// is prompted with a standard File Save dialog.
// If the filename includes an extension (.tif, .tiff, .mpt, .pdf or .dcx)
// then the corresponding format is used for the file.
// If you do not supply an extension, the default multipage format is used.

// Return values:
//	 0	success
//	-1	user cancelled File Save dialog
//	-2	file open error (invalid path or name, or access denied)
//  -3  file format not available
//  -5  other unspecified internal error
//  -6  multipage file already open
//  -7  Multipage support is not installed.

int EZTAPI TWAIN_DibWritePage(HDIB hdib);
//   0	success
//  -2  internal limit exceeded or insufficient memory
//  -3  File format is not available (EZxxx DLL not found)
//  -4  Write error: Output device is full?
//  -5  invalid/unrecognized file format or 'other' - internal
//  -6  multipage file not open
//  -7  Multipage support is not installed.

int EZTAPI TWAIN_WritePageAndFree(HDIB hdib);
// Like TWAIN_DibWritePage followed by DIB_Free.
// The advantage is that the write can be done on a background thread
// without making a copy of the image.

int EZTAPI TWAIN_EndMultipageFile(void);
//   0	success
//  -3  File format is not available
//  -4  Write error - drive offline, or ?? (very unlikely)
//  -5  invalid/unrecognized file format or other internal error
//  -6  multipage file not open
//  -7  Multipage support is not installed.

int EZTAPI TWAIN_MultipageCount(void);
// Return the number of images (scans) written to the most recently
// started multipage file.  In other words, this returns a counter
// which is reset by BeginMultipageFile, and is incremented by DibWritePage.

BOOL EZTAPI TWAIN_IsMultipageFileOpen(void);
// Return True if a multipage output file is open, False otherwise.
// Only one multipage output file can be open at a time (per process.)

#ifndef VISUAL_BASIC

LPCSTR EZTAPI TWAIN_LastOutputFile(void);
// Return the name of the last file written by EZTwain.
// Useful if you pass NULL or the empty string as a filename to
// DIB_WriteToFilename or TWAIN_AcquireToFilename, etc.

#endif

void EZTAPI TWAIN_SetOutputPageCount(int nPages);
// Tell EZTwain how many pages you are about to write to a file.
// This is OPTIONAL: The only effect is to add PageNumber tags
// to TIFF files.  You can use nPages=0, which means "I don't know".

int EZTAPI TWAIN_FileCopy(LPCSTR pzInFile, LPCSTR pzOutFile, int nOptions);
// Read all the images or pages from the in file and write them to the out file.
// nOptions is currently not used and should be 0.
// The formats need not be the same, in fact this function is most often
// used to convert for example from TIFF to PDF.  If you specify a single-image
// output format (BMP, GIF, PNG, JPG) the input file must have only one page.
// Return values:
//	 0	success
//	-1	user cancelled
//	-2	file open error (invalid path or name, or access denied)
//  -3  file format not available or inappropriate (e.g. copying 5-page TIF to JPEG)
//  -5  other unspecified internal error
//  -7  Multipage support is not installed.

//--------- Network file transfer services
//
// These functions require EZCurl.dll to be
// in the same folder as Eztwain3.dll

BOOL EZTAPI UPLOAD_IsAvailable(void);
// TRUE(1) if uploading services are available (= EZCurl.dll can be loaded.)
// Returns FALSE(0) otherwise.

int EZTAPI UPLOAD_Version(void);
// Return the upload module version * 100.

int EZTAPI UPLOAD_MaxFiles(void);
// Return the maximum number of files that can be uploaded in one UPLOAD operation.
// i.e. UPLOAD_FilesToURL, UPLOAD_DibsSeparatelyToURL.

BOOL EZTAPI UPLOAD_AddFormField(const char *fieldName, const char *fieldValue);
// Set a form field to a value in the next Upload (see below).
// The name of the field must be expected by the page/script you upload to.
// All fields set with this function are discarded and forgotten after
// the next upload that uses them.
//
// For example, suppose you have been uploading scanned documents to your server
// using a web form like this:
// <form name="form1" method="post" action="http://server.com/newdoc.php" >
// <input type="hidden" name="key" value="12345678">
// <input type="text" name="vendor id">
// <input type="file" name="file">
// <input type="submit" name="submit" value="Submit">
// </form>
//
// You might automate the upload of a just-scanned image in memory (hdib)
// with vendor id = 1290331, with code similar to this:
//    UPLOAD_AddFormField("key", "12345678")
//    UPLOAD_AddFormField("vendor id", "1290331")
//    UPLOAD_DibToURL(hdib, "http://server.com/newdoc.php", "document.pdf", "file")

BOOL EZTAPI UPLOAD_AddHeader(const char *header);
// Add a header line to the next HTTP upload.
// You should have some understanding of HTTP protocol to use this!
// Don't include any line-break characters.
// To send a cookie, use UPLOAD_AddCookie (below).

BOOL EZTAPI UPLOAD_AddCookie(const char *cookie);
// Add a cookie line to the next HTTP upload.
// Often used to provide session id's e.g.
//    UPLOAD_AddCookie("ASP.NET_SessionID=" & strSessionID)
// or
//    UPLOAD_AddCookie("JSESSIONID=" & strSessionID)

void EZTAPI UPLOAD_EnableProgressBar(BOOL bEnable);
BOOL EZTAPI UPLOAD_IsEnabledProgressBar(void);
// Enable or disable the progress-bar during uploads.
// Default state is enabled (TRUE).

int EZTAPI UPLOAD_DibToURL(HDIB hdib, const char *URL, const char *fileName, const char *fieldName);
int EZTAPI UPLOAD_DibsToURL(const HDIB ahdib[], int n, const char *URL, const char *fileName, const char *fieldName);
int EZTAPI UPLOAD_DibsSeparatelyToURL(const HDIB ahdib[], int n, const char *URL, const char *fileName, const char *fieldName);
int EZTAPI UPLOAD_FilesToURL(const char *files, const char *URL, const char *fieldName);
// Upload an image, set of images, or some files on disk, to a script on a server,
// AS IF a form was being submitted via HTTP-POST, with a field or fields of type 'file'.
//
// Important Note - This confuses some people, don't let it happen to you!
// Only UPLOAD_FilesToURL looks for actual disk files and uploads them.
// All the other UPLOAD functions upload image data, *pretending* it is from a file - no such
// file is read, used, or created on the client machine.
//
// UPLOAD_DibsSeparatelyToURL uploads each image as a separate file, appending '1', '2', etc.
// to both the filename and the fieldname.  So if you upload n images with fileName="page.jpg"
// and fieldName="file", it will upload files as "file1"="page1.jpg", "file2=page2.jpg", etc.
//
// Similarly, UPLOAD_FilesToURL uploads multiple files, appending the counter to the fieldName.
// If you specify a fieldName of "file", UPLOAD_FilesToURL will use "file1", "file2", etc.
// Note that this applies even if you upload just one file.
//
// hdib      = handle to image to upload.
// ahdib     = address or reference to array of hdibs (image handles).
// n         = number of images in array ahdib.
// fileName  = name of (imaginary) file being uploaded.
//             Note: the extension on the filename determines the file format.
// files     = a string containing one or more filenames, separated by semicolons (;) or vertical bars (|)
// URL       = URL to POST the file to, such as http://www.dosadi.com/upload.php
// fieldName = name of the form-field. If null or blank, "file" is used.
//
// NOTE: When uploading multiple images as a single file, you must of course
// use a file format that supports multiple pages: TIFF, PDF, or DCX.
//
// Return values:
//    0    success (transaction completed)
//         Important: A success return (0) means only that the data was sent to the
//         server and a response was received, not that the receiving script
//         necessarily accepted the submitted file.  See DIB_UploadResponse below. 
//   -1	   user cancelled File Save dialog (should never happen)
//   -2	   could not write temp file - access denied, volume protected, etc.
//   -3    a) image is invalid (null or invalid DIB handle)
//         b) The DLL(s) needed to save that format failed to load
//         c) DIB format incompatible with save format e.g. uploading a B&W image as JPEG.
//         d) fileName does not have a recognized extension (.tif, .jpg, .gif, etc)
//   -4    writing data failed, maybe the disk with the temp folder is full?
//   -5    other unspecified internal error
// -100+n  libcurl returned error code n
//         for example:
// -106    could not resolve host
// -107    couldn't connect
// -126    could not open/read local file

void EZTAPI UPLOAD_SetProxy(LPCSTR hostport, LPCSTR userpwd, BOOL bTunnel);

LPCSTR EZTAPI UPLOAD_Response(void);
// Return the text received from the server in response to the last upload.
// You can check this text to see if the server-script accepted the upload.
// There is no predefined limit to the length of the returned string - please
// code defensively.  This call is extremely fast, 
// (See DIB_PostToURL above.)

int EZTAPI UPLOAD_ResponseLength(void);
// Return the length of the last server response string, as returned
// by UPLOAD_Response.

void EZTAPI UPLOAD_GetResponse(LPSTR ResponseText);
// Retrieve the text received from the server in response to the last upload.
// * This text is limited to 1024 characters. *
// (See DIB_PostToURL above.)

void EZTAPI UPLOAD_ClearResponse(void);

#ifndef _XDEFS_
// Upload callback support
// Don't even try to support callbacks in other languages.

typedef BOOL (WINAPI *UPLOADCALLBACK)(LPCSTR status, LPVOID data);

void EZTAPI UPLOAD_SetProgressCallback(UPLOADCALLBACK callback, LPVOID data);
// Establish a function to be called to report on progress of uploads.
// The function call be NULL which of course disables callbacks.
// If non-null, the callback function is called with the data parameter as argument,
// and the upload status (a string) as the 2nd argument.
// The status string can be displayed, but it has a fixed format so it can be parsed:
// The following status strings are defined, but there may be others in the future!
// started:<total bytes to upload>
// stopped
// progress:nnn%
// server response:<server response>
//
// Note that 'stopped' is always reported, whether the upload aborts or succeeds.

#endif

//--------- Application Registration and Licensing

void EZTAPI TWAIN_SetAppTitle(LPCSTR pzAppTitle);
// The short form of Application/Product name registration.
// Sets the product name as far as EZTwain and TWAIN are concerned.
// This title is used in several ways:
// As the title (caption) of any EZTwain dialog boxes / error boxes.
// In the progress box of some devices as they transfer images.
// In the 'software' field of saved image files in some formats,
// including TIFF.

void EZTAPI TWAIN_SetApplicationKey(int nKey);
// Unlock EZTwain Pro for use with the current application - call this AFTER
// calling RegisterApp or SetAppTitle above:  The nKey value must match
// the application title (product name) passed to one of those functions.

void EZTAPI TWAIN_ApplicationLicense(LPCSTR pzAppTitle, int nAppKey);
// Unlock EZTwain using a Single Application License.

void EZTAPI TWAIN_SetVendorKey(LPCSTR pzVendorName, int nKey);
// Unlock EZTwain using a Universal Application / Vendor License

void EZTAPI TWAIN_OrganizationLicense(LPCSTR pzOrganization, int nKey);
// Unlock EZTwain using an Organization / In-House Application License.

BOOL EZTAPI TWAIN_RenewTrialLicense(int uKey);
// Renew or recreate the EZTwain Pro trial license in this computer,
// if the Key parameter is a valid trial-renewal key.
// Such keys are valid only for some number of days after issue.
// Contact Dosadi Support (support@dosadi.com) for such a key.

BOOL EZTAPI TWAIN_SingleMachineLicense(const char* pzMsg);
// If no valid EZTwain Pro license is found on this computer, prompt
// the user with a dialog box asking for a single-machine license key.
// If the user supplies a key, try to record & validate it.
// Return value:
// TRUE if EZTwain Pro is licensed for use on this computer.
// (Note this could be because of a trial license, or an organization license).
// FALSE if EZTwain Pro is not licensed for use on this computer.

void EZTAPI TWAIN_RegisterApp(
    int   nMajorNum,      // major and incremental revision of application.
    int   nMinorNum,      // e.g. version 4.5: nMajorNum = 4, nMinorNum = 5
    int   nLanguage,      // (human) language (use TWLG_xxx from TWAIN.H)
    int   nCountry,       // country (use TWCY_xxx from TWAIN.H)
    LPCSTR pzVersion,     // version info string e.g. "1.0b3 Beta release"
    LPCSTR pzMfg,         // name of mfg/developer e.g. "Crazbat Software"
    LPCSTR pzFamily,      // product family e.g. "BitStomper"
    LPCSTR pzAppTitle);   // specific product e.g. "BitStomper Deluxe Pro"
//
// TWAIN_RegisterApp can be called *AS THE FIRST CALL*, to register the
// application. If this function is not called, the application is given a
// 'generic' registration by EZTWAIN.
// Registration only provides this information to the Source Manager and any
// sources you may open - it is used for debugging, and possibly by some
// sources to give special treatment to certain applications.

//--------- Error Analysis and Reporting ------------------------------------
//
// EZTwain Error codes
typedef enum {
	EZTEC_NONE,					//  0 no error
	EZTEC_START_TRIPLET_ERRS,	//  1
	EZTEC_CAP_GET,				//  2 MSG_GET triplet on a capability failed
	EZTEC_CAP_SET,				//  3 MSG_SET triplet on capability failed
	EZTEC_DSM_FAILURE,			//  4 TWAIN DSM returned TWRC_FAILURE
	EZTEC_DS_FAILURE,			//  5 source returned TWRC_FAILURE
    EZTEC_XFER_FAILURE,         //  6 image transfer failed
	EZTEC_END_TRIPLET_ERRS,		//  7
    EZTEC_OPEN_DSM,             //  8 opening DSM failed
    EZTEC_OPEN_DEFAULT_DS,      //  9 unable to open default TWAIN device
	EZTEC_NOT_STATE_4,			// 10 operation invoked in wrong state
	EZTEC_NULL_HCON,			// 11 MSG_GET returned a null container handle
	EZTEC_BAD_HCON,			    // 12 MSG_GET returned an invalid/unlockable container handle
	EZTEC_BAD_CONTYPE,			// 13 returned container ConType is not valid.
	EZTEC_BAD_ITEMTYPE,		    // 14 returned container ItemType is not valid.
	EZTEC_CAP_GET_EMPTY,		// 15 returned container has 0 items.
	EZTEC_CAP_SET_EMPTY,		// 16 trying to restrict a cap to empty set
    EZTEC_INVALID_HWND,         // 17 function passed an invalid window handle
    EZTEC_PROXY_WINDOW,         // 18 internal proxy window create failed (unlikely!)
    EZTEC_USER_CANCEL,          // 19 user cancelled operation
    EZTEC_RESOLUTION,           // 20 Set failed for Resolution
    EZTEC_LICENSE,              // 21 no valid license found
    EZTEC_JPEG_DLL,             // 22 EZJpeg.dll not found or could not be loaded.
    EZTEC_SOURCE_EXCEPTION,     // 23 a fatal exception occurred in the device driver
    EZTEC_LOAD_DSM,             // 24 unable to find & load DSM
    EZTEC_NO_SUCH_DS,           // 25 OpenSource called with unrecognized source name
    EZTEC_OPEN_DS,              // 26 unable to open device
    EZTEC_ENABLE_FAILED,        // 27 DS failed to enable (go to State 5)
    EZTEC_BAD_MEMXFER,          // 28 something invalid about memory transfer
    EZTEC_JPEG_GRAY_OR_RGB,     // 29 only grayscale and RGB can be saved as JPEG
    EZTEC_JPEG_BAD_Q,           // 30 invalid quality value for JPEG
    EZTEC_BAD_DIB,              // 31 invalid image (HDIB) handle or bitmap header
    EZTEC_BAD_FILENAME,         // 32 null, empty, or wrong syntax filename
    EZTEC_FILE_NOT_FOUND,		// 33
    EZTEC_FILE_ACCESS,          // 34 it's not a file, or you don't have necessary permissions
    EZTEC_MEMORY,               // 35 memory allocation failed
    EZTEC_JPEG_ERR,             // 36 some error parsing JPEG file
    EZTEC_JPEG_ERR_REPORTED,    // 37 error reading JPEG, reported to user
    EZTEC_0_PAGES,              // 38 multipage file written with 0 pages
    EZTEC_UNK_WRITE_FF,         // 39 unrecognized or unsupported output file format
    EZTEC_NO_TIFF,              // 40 TIFF support not available
    EZTEC_TIFF_ERR,				// 41 error reading or writing a TIFF file
    EZTEC_PDF_WRITE_ERR,        // 42 error writing a PDF file
    EZTEC_NO_PDF,               // 43 PDF support not available
    EZTEC_GIFCON,               // 44 error quantizing image for GIF output
    EZTEC_FILE_READ_ERR,        // 45 some error reading a file (%s)
    EZTEC_BAD_REGION,           // 46 region is invalid: empty, off-page, or ?
    EZTEC_FILE_WRITE,           // 47 some error writing a file (%s)
    EZTEC_NO_DS_OPEN,           // 48 "No TWAIN device is currently open (%s)"
    EZTEC_DCXCON,               // 49 error converting image to 1-bit DCX file
    EZTEC_NO_BARCODE,           // 50 barcode recognition services not available
    EZTEC_UNK_READ_FF,          // 51 unrecognized or unsupported file format
    EZTEC_DIB_FORMAT,           // 52 operation not supported on DIB of this format
    EZTEC_PRINT_ERR,            // 53 some failure while printing
    EZTEC_NO_DCX,               // 54 DCX support (EZDcx.dll) not found or damaged
    EZTEC_APP_BAD_CON,          // 55 bad container passed in from application
    EZTEC_LIC_KEY,              // 56 license key/basis mismatch
    EZTEC_INVALID_PARAM,        // 57 invalid parameter to EZTwain function
    EZTEC_INTERNAL,             // 58 some unexpected internal failure
    EZTEC_LOAD_DLL,             // 59 required DLL not found, or didn't load & initialize
    EZTEC_CURL,                 // 60 (lib)curl error
    EZTEC_MULTIPAGE_OPEN,       // 61 multipage file never closed
    EZTEC_BAD_SHUTDOWN,         // 62 Some problem at termination/shutdown/unload
    EZTEC_DLL_VERSION,          // 63 Supporting DLL is incompatible version
	EZTEC_OCR_ERR,				// 64 OCR error or problem %s
	EZTEC_ONLY_TO_PDF,			// 65 Operation only supported on PDF: %s
	EZTEC_APP_TITLE,			// 66 app title set to something invalid
	EZTEC_PATH_CREATE,			// 67 unable to create folder, or path to file. %s
	EZTEC_LATE_LIC,				// 68 "License key provided after it was needed by %s"
    EZTEC_PDF_PASSWORD,         // 69 PDF: password not supplied or incorrect.
    EZTEC_PDF_UNSUPPORTED,      // 70 PDF: uses a feature we don't support
    EZTEC_PDF_BAFFLED,          // 71 PDF: is incomprehensible
    EZTEC_PDF_INVALID,          // 72 PDF: seems to be invalid
    EZTEC_PDF_COMPRESSION,      // 73 PDF: error decompressing (or maybe compressing)
    EZTEC_NOT_ENOUGH_PAGES,     // 74 not enough pages in last file: %s
    EZTEC_DIB_ARRAY_OVERFLOW,   // 75 too many images to fit in provided array
    EZTEC_DEVICE_PAPERJAM,      // 76 scanner reports a paper jam
    EZTEC_DEVICE_DOUBLEFEED,    // 77 scanner reports a double feed
    EZTEC_DEVICE_COMM,          // 78 communication error with device
    EZTEC_DEVICE_INTERLOCK,     // 79 device reports cover or door open
	EZTEC_BAD_DOC,				// 80 invalid document (HDOC) parameter
	EZTEC_OTHER_DS_OPEN,		// 81 other TWAIN source already open (open error)
} EZTWAIN_ERROR_CODE;


unsigned EZTAPI TWAIN_GetResultCode(void);
// Return the result code (TWRC_xxx) from the last triplet sent to TWAIN

unsigned EZTAPI TWAIN_GetConditionCode(void);
// Return the condition code from the last triplet sent to TWAIN.
// If a source is NOT open, return the condition code of the source manager.

BOOL EZTAPI TWAIN_UserClosedSource(void);
// Return TRUE (1) if during the last acquire the user asked
// the DataSource to close.  0 otherwise of course.
// This flag is cleared each time you start any kind of acquire,
// and it is set if EZTWAIN receives a
// MSG_CLOSEDSREQ message through TWAIN.

void EZTAPI TWAIN_ErrorBox(LPCSTR pzMsg);
// Post an error message dialog with an OK button.
// pzMsg points to a null-terminated message string.
// The box caption is the current AppTitle - see SetAppTitle.
// If messages are suppressed (see below) this function does nothing.

BOOL EZTAPI TWAIN_SuppressErrorMessages(BOOL bYes);
// Enable or disable EZTWAIN error messages to the user.
// When bYes = FALSE(0), error messages are displayed.
// When bYes = TRUE(non-0), error messages are suppressed.
// By default, error messages are displayed.
// Returns the previous state of the flag.
//
// EZTWAIN cannot suppress messages from TWAIN or TWAIN device drivers.

void EZTAPI TWAIN_ReportLastError(LPCSTR msg);
// If EZTwain has recorded an error and that error has not been
// reported to the user, this function displays a modal error dialog
// with information about that error.
// If msg is non-null and not the empty string, it is included
// in the dialog box.
// Many EZTwain errors record additional details, and those details
// are also inserted in the error dialog.
//
// If the recorded error is EZTEC_NONE (no error) or EZTEC_USER_CANCEL,
// no error dialog is displayed.
// If the recorded error information indicates that the user cancelled
// a TWAIN operation, *or* that the user has already seen an error
// message about the error, then no error dialog is displayed.
//
// This function *clears* the recorded error, whether or
// not it displays a message, by calling TWAIN_ClearError.

void EZTAPI TWAIN_GetLastErrorText(LPSTR pzMsg);
// Get a string that describes the last error detected by EZTwain.
// Note: This function is called by TWAIN_ReportLastError.
// Note: The returned string may contain end-of-line characters.
// The parameter is a string variable (char array in C/C++).
// You are responsible for allocating room for 512 8-bit characters
// in the string variable before calling this function.

LPCSTR EZTAPI TWAIN_LastErrorText(void);
// Return a string that describes the last error detected by EZTwain -
// see Notes for TWAIN_GetLastErrorText.

int EZTAPI TWAIN_LastErrorCode(void);
// Return the last internal EZTWAIN error code. (see EZTEC_ codes above)

void EZTAPI TWAIN_ClearError(void);
// Set the EZTWAIN internal error code to EZTEC_NONE

void EZTAPI TWAIN_RecordError(int code, LPCSTR note);
// Set the internal EZTwain error code, if it is not set already.
// This is the error info that is reported by LastErrorCode, LastErrorText,
// ReportLastError, and so on.
// The error code can be cleared by TWAIN_ClearError, and a few other
// functions also clear it.

BOOL EZTAPI TWAIN_ReportLeaks(void);
// Display a message box if EZTwain can detect any memory leaks.
// Currently this only counts image handles (DIBs) that have been
// allocated but never freed.
// Returns True(1) if a problem is detected, False(0) otherwise.


//--------- TWAIN State Control ------------------------------------

void EZTAPI TWAIN_Shutdown(void);
// Shuts down and cleans up all EZTwain operations.
// All memory allocations are freed, all I/O operations
// are completed, any threads are terminated, and
// TWAIN is closed and unloaded.

BOOL EZTAPI TWAIN_LoadSourceManager(void);
// Finds and loads the Data Source Manager, TWAIN.DLL.
// If Source Manager is already loaded, does nothing and returns TRUE(1).
// This can fail if TWAIN.DLL is not installed (in the right place), or
// if the library cannot load for some reason (insufficient memory?) or
// if TWAIN.DLL has been corrupted.

BOOL EZTAPI TWAIN_OpenSourceManager(HWND hwnd);
// Opens the Data Source Manager, if not already open.
// If the Source Manager is already open, does nothing and returns TRUE.
// This call will fail if the Source Manager is not loaded.

BOOL EZTAPI TWAIN_OpenDefaultSource(void);
// This opens the source selected in the Select Source dialog.
// If some source is already open, does nothing and returns TRUE.
// Will load and open the Source Manager if needed.
// If this call returns TRUE, TWAIN is in STATE 4 (TWAIN_SOURCE_OPEN)

// These two functions allow you to enumerate the available data sources:
BOOL EZTAPI TWAIN_GetSourceList(void);
// Fetches the list of sources into memory, so they can be returned
// one by one by TWAIN_GetNextSourceName, below.
// Returns TRUE (1) if successful, FALSE (0) otherwise.
// Note: In the special (and very unusual) case of an empty list,
// this function returns TRUE(1) if there was no other error.

BOOL EZTAPI TWAIN_GetNextSourceName(LPSTR pzName);
// Copies the next source name in the list into its parameter.
// The parameter is a string variable (char array in C/C++).
// You are responsible for allocating room for 33 8-bit characters
// in the string variable before calling this function.
// Returns TRUE (1) if successful, FALSE (0) if there are no more.

LPCSTR EZTAPI TWAIN_NextSourceName(void);
// Returns the next source name in the list.
// Returns the empty string when it comes to the end of the list.

BOOL EZTAPI TWAIN_GetDefaultSourceName(LPSTR pzName);
// Copies the name of the TWAIN default source into its parameter.
// This is the global 'default source' as defined by TWAIN - which can
// only be set by a user in the Select Source dialog, which
// is displayed by (TWAIN_)SelectImageSource.
//
// Normally returns TRUE (1) but could return FALSE (0) if:
//   - the TWAIN Source Manager cannot be loaded & initialized or
//   - there is no current default source (e.g. no sources are installed)
//
// The parameter is a string variable (char array in C/C++).
// You are responsible for allocating room for 33 8-bit characters
// in the string variable before calling this function.

LPCSTR EZTAPI TWAIN_DefaultSourceName(void);
// Like GetDefaultSourceName but returns a string

BOOL EZTAPI TWAIN_OpenSource(LPCSTR pzName);
// Opens the source with the given name.
// If that source is already open, does nothing and returns TRUE.
// If another source is open, closes it and attempts to open the specified source.
// Will load and open the Source Manager if needed.

BOOL EZTAPI TWAIN_EnableSource(HWND hwnd);
// Enables the open Data Source. This posts the source's user interface
// and allows image acquisition to begin.  If the source is already enabled,
// this call does nothing and returns TRUE.

BOOL EZTAPI TWAIN_DisableSource(void);
// Disables the open Data Source, if any.
// This closes the source's user interface.
// If successful or the source is already disabled, returns TRUE(1).

BOOL EZTAPI TWAIN_CloseSource(void);
// Closes the open Data Source, if any.
// If the source is enabled, disables it first.
// If successful or source is already closed, returns TRUE(1).

BOOL EZTAPI TWAIN_CloseSourceManager(HWND hwnd);
// Closes the Data Source Manager, if it is open.
// If a source is open, disables and closes it as needed.
// If successful (or if source manager is already closed) returns TRUE(1).

BOOL EZTAPI TWAIN_UnloadSourceManager(void);
// Unloads the Data Source Manager i.e. TWAIN.DLL - releasing
// any associated memory or resources.
// If necessary, it will abort transfers, close the open source
// if any, and close the Source Manager.
// If successful, it returns TRUE(1)

#ifndef _XDEFS_

BOOL EZTAPI TWAIN_MessageHook(LPMSG lpmsg);
// This function detects Windows messages that should be routed
// to an enabled Data Source, and picks them off.  In a full TWAIN
// app, TWAIN_MessageHook is called inside the main GetMessage loop.

#endif

BOOL EZTAPI TWAIN_IsTransferReady(void);

BOOL EZTAPI TWAIN_EndXfer(void);

BOOL EZTAPI TWAIN_AbortAllPendingXfers(void);

//--------- High-level Capability Negotiation Functions --------

// These functions should only be called in State 4 (TWAIN_SOURCE_OPEN)

BOOL EZTAPI TWAIN_SetXferCount(int nXfers);
// Negotiate with open Source the number of images application will accept.
// nXfers = -1 means any number
// Returns: TRUE(1) for success, FALSE(0) for failure.

//----- Unit of Measure
// TWAIN unit codes (from twain.h)
#define TWUN_INCHES      0
#define TWUN_CENTIMETERS 1
#define TWUN_PICAS       2
#define TWUN_POINTS      3
#define TWUN_TWIPS       4
#define TWUN_PIXELS      5

int EZTAPI TWAIN_GetCurrentUnits(void);
// Return the current unit of measure: inches, cm, pixels, etc.
// Many TWAIN parameters such as resolution are set and returned
// in the current unit of measure.
// There is no error return - in case of error it returns 0 (TWUN_INCHES)

BOOL EZTAPI TWAIN_SetUnits(int nUnits);
BOOL EZTAPI TWAIN_SetCurrentUnits(int nUnits);		// older form
// Set the current unit of measure for the source.
// Returns: TRUE(1) for success, FALSE(0) for failure.
// Common unit codes (TWUN_*) are given above.
// Notes:
// 1. Most sources do not support all units, some support *only* inches!
// 2. If you want to get or set resolution in DPI (dots per *inch*), make
// sure the current units are inches, or you might get Dots-Per-cm!
// 3. Ditto (same comment) for ImageLayout, see below.

int EZTAPI TWAIN_GetBitDepth(void);
// Get the current bitdepth, which can depend on the current PixelType.
// Bit depth is per color channel e.g. 24-bit RGB has bit depth 8.
// If anything goes wrong, this function returns 0.

BOOL EZTAPI TWAIN_SetBitDepth(int nBits);
// (Try to) set the current bitdepth (for the current pixel type).
// Note: You should set a PixelType, then set the bitdepth for that type.
// Returns: TRUE(1) for success, FALSE(0) for failure.

//------- TWAIN Pixel Types (from twain.h)
#define TWPT_BW          0	// 1-bit per pixel, black and white
#define TWPT_GRAY        1	// grayscale, 8 or 4-bit
#define TWPT_RGB         2	// RGB color, 24-bit (rarely, 15,16,32-bit)
#define TWPT_PALETTE     3	// indexed color (image has a color table) 8 or 4-bit.
#define TWPT_CMY         4	// CMY color, 24-bit
#define TWPT_CMYK        5	// CMYK color, 32-bit

int EZTAPI TWAIN_GetPixelType(void);
// Ask the source for the current pixel type.
// If anything goes wrong (it shouldn't), this function returns 0 (TWPT_BW).

BOOL EZTAPI TWAIN_SetPixelType(int nPixType);
BOOL EZTAPI TWAIN_SetCurrentPixelType(int nPixType);		// older form
// Try to set the current pixel type for acquisition.
// The source may select this pixel type, but don't assume it will.

double EZTAPI TWAIN_GetCurrentResolution(void);
// Ask the source for the current (horizontal) resolution.
// Resolution is in dots per current unit! (See TWAIN_GetCurrentUnits above)
// If anything goes wrong (it shouldn't) this function returns 0.0

double EZTAPI TWAIN_GetXResolution(void);
double EZTAPI TWAIN_GetYResolution(void);
// Returns the current horizontal or vertical resolution, in dots per *current unit*.
// In the event of failure, returns 0.0.

BOOL EZTAPI TWAIN_SetResolution(double dRes);
BOOL EZTAPI TWAIN_SetResolutionInt(int nRes);
BOOL EZTAPI TWAIN_SetCurrentResolution(double dRes);		// older form
// Try to set the current resolution (in both x & y).
// Resolution is in dots per current unit! (See TWAIN_GetCurrentUnits above)
// Note: The source may select this resolution, but don't assume it will.

// You can also set the resolution in X and Y separately, if your TWAIN
// device can handle this:
BOOL EZTAPI TWAIN_SetXResolution(double dxRes);
BOOL EZTAPI TWAIN_SetYResolution(double dyRes);

BOOL EZTAPI TWAIN_SetContrast(double dCon);
// Try to set the current contrast for acquisition.
// The TWAIN standard *says* that the range for this cap is -1000 ... +1000

BOOL EZTAPI TWAIN_SetBrightness(double dBri);
// Try to set the current brightness for acquisition.
// The TWAIN standard *says* that the range for this cap is -1000 ... +1000

BOOL EZTAPI TWAIN_SetThreshold(double dThresh);
// Try to set the threshold for black and white scanning.
// Should only affect 1-bit scans i.e. PixelType == TWPT_BW.
// The TWAIN default threshold value is 128.
// After staring at the TWAIN 1.6 spec for a while, I imagine that it implies
// that for 8-bit samples, values >= nThresh are thresholded to 1, others to 0.

double EZTAPI TWAIN_GetCurrentThreshold(void);
// Try to get and return the current value (MSG_GETCURRENT) of the
// ICAP_THRESHOLD capability.  If this fails for any reason, it
// will return -1.  *VERSIONS BEFORE 2.65 RETURNED 128.0*

//--------------------------------------------------------------
// Automatic post-processing of scanned pages
//
//
// Automatic deskewing of scanned pages
//
void EZTAPI TWAIN_SetAutoDeskew(int nMode);
// Select the 'auto-deskew' mode.
// Auto-deskew attempts to straighten up scans that are slightly crooked,
// up to about 10 degrees.
// The currently defined modes are:
//  0   - no auto deskew (default)
//  1   - auto deskew using EZTwain software algorithms

int EZTAPI TWAIN_GetAutoDeskew(void);
// Return the current AutoDeskew mode.

//
// Automatic discarding of blank pages
//
void EZTAPI TWAIN_SetBlankPageMode(int nMode);
int EZTAPI TWAIN_GetBlankPageMode(void);
// Sets or gets the 'Skip Blank Pages' mode.
// The currently defined modes are:
//   0 = no special treatment for blank pages (default)
//   1 = blank pages are discarded by all multipage Acquire functions.
// See TWAIN_SetBlankPageThreshold below for more details.

void EZTAPI TWAIN_SetBlankPageThreshold(double dDarkness);
double EZTAPI TWAIN_GetBlankPageThreshold(void);
// Sets or gets the blank page 'darkness' threshold.
// In 'Skip Blank Pages' mode (see above), each page of a multipage
// scan is measured for 'darkness'.  If the darkness of a page
// is below the BlankPageThreshold, it is considered blank.
// See the related functions DIB_IsBlank and DIB_Darkness.
// 
// The default BlankPageThreshold is 0.02 (= 2% dark pixels).

int EZTAPI TWAIN_BlankDiscardCount(void);
// Return the number of blank pages discarded (skipped) during
// the most recent multipage scan.
// Of course this only reports pages skipped by software, not
// any pages discarded as 'blank' inside the scanner - if such
// a feature is enabled.
//
// Automatic cropping of scanned pages
//
void EZTAPI TWAIN_SetAutoCrop(int nMode);
int EZTAPI TWAIN_GetAutoCrop(void);
// Select the AutoCrop mode.
// Auto-crop attempts to trim off black areas on the outside
// edges of each incoming image during scanning.
// It will not be effective on scanners that have white
// background outside the scanned document.
// The currently defined modes are:
//  0   - no auto crop (default)
//  1   - auto crop using EZTwain software algorithms
//  2   - use scanner autocrop if possible, otherwise no autocrop
//  3   - use scanner autocrop if possible, otherwise do software autocrop.

void EZTAPI TWAIN_SetAutoCropOptions(int nOpts);
int EZTAPI TWAIN_GetAutoCropOptions(void);
// Set/get the Options flags for auto-crop during scanning.
// See DIB_AutoCrop for details of these flags.

void EZTAPI TWAIN_SetAutoCropSize(double w, double h, int nUnits);
// Set the width & height for subsequent auto-crops, in the given units.
// This restricts subsequent auto-crops to select the best-match crop
// position of the specified size.
// Use this call if you know the size of the expected document.
// For units, see (TWAIN_)GetCurrentUnits.
//
// Note: This setting persists until changed! You must clear it explicitly.
// To clear, use SetAutoCropSize(0,0) or call ClearAutoCropSize (below)

void EZTAPI TWAIN_ClearAutoCropSize(void);
// Clear any restrictions on auto-crop size.

//
// Automatic contrast adjustment of scanned pages
//
void EZTAPI TWAIN_SetAutoContrast(int nMode);
int EZTAPI TWAIN_GetAutoContrast(void);
// Select the AutoContrast mode.
// Automatically adjust the contrast of each image - see
// DIB_AutoContrast for more information.
// The currently defined modes are:
//  0   - no autocontrast.
//  1   - autocontrast using EZTwain software algorithms

//
// Automatic OCR of scanned pages.
//
void EZTAPI TWAIN_SetAutoOCR(int nMode);
int EZTAPI TWAIN_GetAutoOCR(void);
// Sets or gets the auto-OCR mode
// By default this mode is 0 = OFF.
// When this mode is on (1), EZTwain applies OCR, if available, to each incoming
// scanned page or image and temporarily stores the result.  In this mode,
// if you are scanning directly to PDF format using TWAIN_AcquireToFilename
// or TWAIN_AcquireMultipageFile, the OCR'd text is also written to each
// PDF page as invisible text, to facilitate indexing and searching.
// If you are scanning individual pages you can call OCR_Text or OCR_GetText
// to retrieve the text found on the most recently scanned page.
// In this mode, any Acquire call discards any previous OCR text.
//
// The currently selected OCR engine is used: See OCR_SelectEngine and co.
// Caution: If OCR fails for some reason in auto-OCR mode, an error is recorded
// (see TWAIN_LastErrorCode, TWAIN_ReportLastError) but the scanning function
// may report success.

//
// Automatic negation of scanned pages
//
void EZTAPI TWAIN_SetAutoNegate(BOOL bYes);
BOOL EZTAPI TWAIN_GetAutoNegate(void);
// Set or get the "AutoNegate" flag: When this flag is set (non-zero)
// EZTwain automatically 'negates' any B&W scanned image that is > 80% black
// i.e. it exchanges black & white in the image.
// This flag is TRUE (1) by default.

//--------------------------------------------------------------


BOOL EZTAPI TWAIN_SetXferMech(int mech);
int EZTAPI TWAIN_XferMech(void);
// Try to set or get the transfer mode - one of the following:
#define XFERMECH_NATIVE    0
#define XFERMECH_FILE      1
#define XFERMECH_MEMORY    2
// It is normally not necessary to set the transfer mode, 
// TWAIN_Acquire, TWAIN_AcquireMultipageFile and the other general-purpose
// scanning functions will select the appropriate transfer mode, taking
// the scanner model and scan settings into account.
//
// If your application is used with a particularly wide variety of scanners,
// you may encounter a user with a scanning problem that is resolved by forcing
// memory transfer mode. To address this, offer a field-settable option that
// adds this call as part of scan-parameter setting:
// TWAIN_SetXferMech(XFERMECH_MEMORY)
//

BOOL EZTAPI TWAIN_SupportsFileXfer(void);
// Returns TRUE(1) if the open DS claims to support file transfer mode (XFERMECH_FILE)
// Returns FALSE(0) otherwise.
// This mode is optional.  If TRUE, you can use AcquireFile.

BOOL EZTAPI TWAIN_SetPaperSize(int nPaper);
// During the next scan, request that the scanner scan the specified paper size.
// Most scanners support the first few paper sizes, excluding any that are
// larger than their physical scan capacity.
// To determine the paper sizes supported by a particular scanner, see
// "Working with Capabilities" in the EZTwain User Guide.
//
// Note - These are synonyms for the TWSS_* constants in TWAIN.H
#define PAPER_NONE        0
#define PAPER_A4LETTER    1
#define PAPER_A4          1		// synonym
#define PAPER_B5LETTER    2
#define PAPER_JISB5        2
#define PAPER_USLETTER    3
#define PAPER_USLEGAL     4
#define PAPER_A5          5
#define PAPER_B4          6
#define PAPER_ISOB4        6
#define PAPER_B6          7
#define PAPER_ISOB6        7
#define PAPER_USLEDGER    9
#define PAPER_USEXECUTIVE 10
#define PAPER_A3          11
#define PAPER_B3          12
#define PAPER_ISOB3        12
#define PAPER_A6          13
#define PAPER_C4          14
#define PAPER_C5          15
#define PAPER_C6          16
#define PAPER_4A0          17
#define PAPER_2A0          18
#define PAPER_A0           19
#define PAPER_A1           20
#define PAPER_A2           21
#define PAPER_A7           22
#define PAPER_A8           23
#define PAPER_A9           24
#define PAPER_A10          25
#define PAPER_ISOB0        26
#define PAPER_ISOB1        27
#define PAPER_ISOB2        28
#define PAPER_ISOB5        29
#define PAPER_ISOB7        30
#define PAPER_ISOB8        31
#define PAPER_ISOB9        32
#define PAPER_ISOB10       33
#define PAPER_JISB0        34
#define PAPER_JISB1        35
#define PAPER_JISB2        36
#define PAPER_JISB3        37
#define PAPER_JISB4        38
#define PAPER_JISB6        39
#define PAPER_JISB7        40
#define PAPER_JISB8        41
#define PAPER_JISB9        42
#define PAPER_JISB10       43
#define PAPER_C0           44
#define PAPER_C1           45
#define PAPER_C2           46
#define PAPER_C3           47
#define PAPER_C7           48
#define PAPER_C8           49
#define PAPER_C9           50
#define PAPER_C10          51
#define PAPER_USSTATEMENT  52
#define PAPER_BUSINESSCARD 53

BOOL EZTAPI TWAIN_GetPaperDimensions(int nPaper, int nUnits, double *pdW, double *pdH);
// Retrieve the width and height of a standard paper size.
// 1st parameter is a PAPER_ code.
// 2nd parameter is a unit code, TWUN_INCHES, TWUN_CENTIMETERS, etc.
// 3rd & 4th parameter are pointers to double variables that receive the width
// and height of the specified paper size, in the specified units.
// Returns TRUE(1) if successful, FALSE(0) otherwise.

//-------- Document Feeder -------

BOOL EZTAPI TWAIN_HasFeeder(void);
// Returns TRUE(1) if the source indicates it has a document feeder.
// Note: A FALSE(0) is returned if the source does not handle this inquiry.

BOOL EZTAPI TWAIN_ProbablyHasFlatbed(void);
// Returns TRUE(1) if we think the source has a flatbed available.
// It's a good guess but not a guarantee - we could be wrong.

BOOL EZTAPI TWAIN_IsFeederSelected(void);
// Returns TRUE(1) if the document feeder is selected.

BOOL EZTAPI TWAIN_SelectFeeder(BOOL bYes);
// (Try to) select or deselect the document feeder.
// The document feeder, if any, is selected if bYes is non-zero.
// The flatbed, if any, is selected if bYes is zero.
// Note: A few of the scanners that have both a flatbed and 
// a feeder ignore this request in some circumstances.
// Returns TRUE(1) if successful, FALSE(0) otherwise.

BOOL EZTAPI TWAIN_IsAutoFeedOn(void);
// Returns TRUE(1) if automatic feeding is enabled, otherwise FALSE(0).
// Make sure the feeder is selected before calling this function.

BOOL EZTAPI TWAIN_SetAutoFeed(BOOL bYes);
// (Try to) turn on/off automatic feeding thru the feeder.
// Returns TRUE(1) if successful, FALSE(0) otherwise.
// Note: TWAIN_AcquireMultipageFile calls TWAIN_SetAutoFeed(True).

BOOL EZTAPI TWAIN_IsFeederLoaded(void);
// Returns TRUE(1) if there are documents in the feeder.
// Make sure the feeder is selected before calling this function.

BOOL EZTAPI TWAIN_IsPaperDetectable(void);
// Returns TRUE(1) if the open device (better have one open!)
// is capable of detecting paper in its feeder.
// If not, returns FALSE.
// Displays an error dialog if called with no scanner open.

BOOL EZTAPI TWAIN_SetAutoScan(BOOL bYes);
// Setting this to TRUE gives the scanner permission to 'scan ahead'
// i.e. to pull pages from the feeder and scan them before 
// they have been requested.  On high-speed scanners, you may
// have to enable AutoScan to achieve the maximum scanning rate.
// Returns TRUE(1) if successful, FALSE(0) otherwise.
// This call will fail on most flatbeds & cameras, and some 'feeder'
// scanners.
// TWAIN_AcquireMultipageFile calls TWAIN_SetAutoScan(True).

//-------- Duplex Scanning -------

int EZTAPI TWAIN_GetDuplexSupport(void);
// Query the device for duplex scanning support.
//   Return values:
// 0    = no support (or error, or query not recognized)
// 1    = 1-pass duplex
// 2    = 2-pass duplex

BOOL EZTAPI TWAIN_EnableDuplex(BOOL bYes);
// Enable (bYes not 0) or disable (bYes=0) duplex scanning.
// Returns TRUE(1) if successful, FALSE(0) otherwise.

BOOL EZTAPI TWAIN_IsDuplexEnabled(void);
// Returns TRUE(1) if the device supports duplex scanning
// and duplex scanning is enabled.  FALSE(0) otherwise.

//--------- Other 'exotic' capabilities --------

int EZTAPI TWAIN_HasControllableUI(void);
// Return 1 if source claims UI can be hidden (see SetHideUI above)
// Return 0 if source says UI *cannot* be hidden
// Return -1 if source (pre TWAIN 1.6) cannot answer the question.

BOOL EZTAPI TWAIN_SetIndicators(BOOL bVisible);
BOOL EZTAPI TWAIN_GetIndicators(void);
// Set/Get the value of CAP_INDICATORS.
// This is set & read from the open Source if a source is open, otherwise
// these functions set & report the value that will be used the next time
// a source is opened.
//
// Default is TRUE, which gives the device permission to show a progress
// box or similar, but does not require it.

int EZTAPI TWAIN_Compression(void);
BOOL EZTAPI TWAIN_SetCompression(int compression);
// Set/Get compression style for transferred data
// Set returns TRUE(1) for success, FALSE(0) for failure.

BOOL EZTAPI TWAIN_Tiled(void);
BOOL EZTAPI TWAIN_SetTiled(BOOL bTiled);
// Set/Get whether source does memory xfer via strips or tiles.
// bTiled = TRUE if it uses tiles for transfer.
// Set returns: TRUE(1) for success, FALSE(0) for failure.

int EZTAPI TWAIN_PlanarChunky(void);
BOOL EZTAPI TWAIN_SetPlanarChunky(int shape);
// Set/Get current pixel shape (TWPC_CHUNKY or TWPC_PLANAR), or -1.
// Set returns TRUE(1) for success, FALSE(0) for failure.

#define CHUNKY_PIXELS    0
#define PLANAR_PIXELS    1

int EZTAPI TWAIN_PixelFlavor(void);
BOOL EZTAPI TWAIN_SetPixelFlavor(int flavor);
// Set/Get pixel 'flavor' - whether a '0' pixel value means black or white:
// Set returns: TRUE(1) for success, FALSE(0) for failure.

#define CHOCOLATE_PIXELS   0  // zero pixel represents darkest shade
#define VANILLA_PIXELS     1  // zero pixel represents lightest shade


BOOL EZTAPI TWAIN_SetLightPath(BOOL bTransmissive);
// Tries to select transparent or reflective media on the open source.
// A parameter of TRUE(1) means transparent, FALSE(0) means reflective.
// Returns: TRUE(1) for success, FALSE(0) for failure.

BOOL EZTAPI TWAIN_SetAutoBright(BOOL bOn);
BOOL EZTAPI TWAIN_SetGamma(double dGamma);
BOOL EZTAPI TWAIN_SetShadow(double d);       // 0..255
BOOL EZTAPI TWAIN_SetHighlight(double d);    // 0..255
// Set auto-brightness, gamma, shadow, and highlight values.
// Refer to the TWAIN specification for definitions of these settings.
// Returns: TRUE(1) for success, FALSE(0) for failure.

//--------- Image Layout (Region of Interest) --------

void EZTAPI TWAIN_SetRegion(double L, double T, double R, double B);
// Specify the region to be acquired, in current unit of measure.
// This is the recommended most-general way to scan a region.
// Tries to use TWAIN_SetImageLayout and TWAIN_SetFrame (see below).
// If the device ignores those, the specified region is extracted
// after each scan completes, by software cropping. (DIB_RegionCopy)
// In other words, this call should *always* produce scans of
// the requested region, unless you specify a region in inches or
// centimeters and the device is a camera whose only unit is pixels.

void EZTAPI TWAIN_ResetRegion(void);
// Clear any region set with TWAIN_SetRegion above.

BOOL EZTAPI TWAIN_SetImageLayout(double L, double T, double R, double B);
// Specify the area to scan, sometimes called the ROI (Region of Interest)
// Returns: TRUE(1) for success, FALSE(0) for failure.
// This call is only valid in State 4.
// L, T, R, B = distance to left, top, right, and bottom edge of
// area to scan, measured in the current unit of measure,
// from the top-left corner of the 'original page' (TWAIN 1.6 8-22)

BOOL EZTAPI TWAIN_GetImageLayout(double *L, double *T, double *R, double *B);
BOOL EZTAPI TWAIN_GetDefaultImageLayout(double *L, double *T, double *R, double *B);
// Get the current or default (power-on) area to scan.
// Returns: TRUE(1) for success, FALSE(0) for failure.
// This call is valid in States 4-6.
// Supposedly the returned values (see above)
// are in the current unit of measure (ICAP_UNITS), but I observe that
// many DS's ignore ICAP_UNITS when dealing with Image Layout.

BOOL EZTAPI TWAIN_ResetImageLayout(void);
// Reset the area to scan to the default (power-on) settings.
// This call is only valid in State 4.
// Returns: TRUE(1) for success, FALSE(0) for failure.


// Closely related:
BOOL EZTAPI TWAIN_SetFrame(double L, double T, double R, double B);
// This is an alternative way to set the scan area.
// Some scanners will respond to this instead of SetImageLayout.
// Returns: TRUE(1) for success, FALSE(0) for failure.
// This call is only valid in State 4.
// L, T, R, B = distance to left, top, right, and bottom edge of
// area to scan, measured in the current unit of measure,


//--------- Tone Response Curves --------

BOOL EZTAPI TWAIN_SetGrayResponse(const long pcurve[256]);
// Define a translation of gray pixel values.
// When device digitizes a pixel with value V, that
// pixel is translated to value pcurve[V] before it
// is returned to the application.
// Device must be open (State 4),
// Current PixelType must be TWPT_GRAY or TWPT_RGB,
// current BitDepth should be 8.
// pcurve must be a table (array, vector) of 256 entries.
// Returns: TRUE(1) for success, FALSE(0) for failure.

BOOL EZTAPI TWAIN_SetColorResponse(const long pred[256], const long pgreen[256], const long pblue[256]);
// Define a translation of color values.
// Like TWAIN_SetGrayResponse (above) but separate translation can
// be applied to each color channel.
// Returns: TRUE(1) for success, FALSE(0) for failure.

BOOL EZTAPI TWAIN_ResetGrayResponse(void);
BOOL EZTAPI TWAIN_ResetColorResponse(void);
// These two functions reset the response curve to map every
// value V to itself i.e. a 'do nothing' translation.
// Returns: TRUE(1) for success, FALSE(0) for failure.

//--------- Barcode Recognition -------

BOOL EZTAPI BARCODE_IsAvailable(void);
// TRUE(1) if barcode recognition is available.
// Returns FALSE(0) otherwise.

int EZTAPI BARCODE_Version(void);
// Return the barcode module version * 100.

// Barcode recognition engines supported by EZTwain:
#define EZBAR_ENGINE_NONE			0       // null engine, no barcode services.
#define EZBAR_ENGINE_DOSADI			1       // Dosadi native barcode recognizer
#define EZBAR_ENGINE_AXTEL			2       // Axtel engine
#define EZBAR_ENGINE_LEADTOOLS15	3		// LEADTOOLS v15 engine
#define EZBAR_ENGINE_BLACKICE		4		// Black Ice engine
#define EZBAR_ENGINE_LEADTOOLS16	5		// LEADTOOLS V16 engine

#define EZBAR_ENGINE_LEADTOOLS		3		// use older LeadTools unless told otherwise

// The Axtel barcode engine has been discontinued by Axtel.
// The LEADTOOLS engine must be separately licensed from LEADTOOLS - www.leadtools.com
// The Black Ice barcode engine must be separately licensed from Black Ice. 

BOOL EZTAPI BARCODE_IsEngineAvailable(int nEngine);
BOOL EZTAPI BARCODE_SelectEngine(int nEngine);
int EZTAPI BARCODE_SelectedEngine(void);

LPCSTR EZTAPI BARCODE_EngineName(int nEngine);
// Returns the short name ("None", "Dosadi", "Axtel", "LEADTOOLS", "Black Ice") of the specified
// engine, or the empty string if nEngine is not a recognized barcode engine code.

void EZTAPI BARCODE_SetLicenseKey(LPCSTR pzKey);
// Supply your license key for the currently selected engine.
// The Dosadi engine does not currently require a key.
// For LeadTools, this is a 1D Barcode Module key obtained from LeadTools

int EZTAPI BARCODE_ReadableCodes(void);
// Return the sum of the barcode types recognized by the current selected engine.
//
// Barcode types:
#define EZBAR_EAN_13		0x00000001L
#define EZBAR_EAN_8		    0x00000002L
#define EZBAR_UPCA		    0x00000004L
#define EZBAR_UPCE		    0x00000008L
#define EZBAR_CODE_39 	    0x00000010L     // 16
#define EZBAR_CODE_39FA     0x00000020L     // 32
#define EZBAR_CODE_128	    0x00000040L     // 64
#define EZBAR_CODE_I25	    0x00000080L     // 128
#define EZBAR_CODA_BAR	    0x00000100L     // 256
#define EZBAR_UCCEAN_128	0x00000200L     // 512
#define EZBAR_CODE_93		0x00000400L     // 1024
#define EZBAR_ANY			-1

LPCSTR EZTAPI BARCODE_TypeName(int nType);
// Return a human-readable name for the specified barcode type/symbology.

BOOL EZTAPI BARCODE_SetDirectionFlags(int nDirFlags);
int EZTAPI BARCODE_GetDirectionFlags(void);
int EZTAPI BARCODE_AvailableDirectionFlags(void);
// Set/Get the directions the engine will scan for barcodes.
// The default is left-to-right ONLY.
// Scanning for barcodes in multiple directions can slow the
// recognition process.  BARCODE_SetDirectionFlags will return TRUE if
// completely successful, FALSE if any direction is invalid or not supported.
// Setting the direction flags to -1 is interpreted as "select all supported
// directions."

// Barcode direction flags - can be or'ed together
#define EZBAR_LEFT_TO_RIGHT     0x01
#define EZBAR_RIGHT_TO_LEFT     0x02
#define EZBAR_TOP_TO_BOTTOM	    0x04
#define EZBAR_BOTTOM_TO_TOP	    0x08
#define EZBAR_DIAGONAL		    0x10
// some common combinations:
#define EZBAR_HORIZONTAL	    0x03    // left-to-right or right-to-left
#define EZBAR_VERTICAL		    0x0C    // top-to-bottom or bottom-to-top

void EZTAPI BARCODE_SetZone(long x, long y, long w, long h);
// Restrict barcode recognition to one zone (in pixels) of each image.
// Coordinates are left pixel, top pixel, width and height in pixels.

void EZTAPI BARCODE_NoZone(void);
// Cancel any zone restriction - subsequent barcode recognition
// applies to the entire image.

int EZTAPI BARCODE_Recognize(HDIB hdib, int nMaxCount, int nType);
// Find and recognize barcodes in the given image.
// Don't look for more than nMaxCount barcodes (-1 means 'any number')
// Expect barcodes of the specified type (-1 means 'any recognized type')
// You can add or 'or' together barcode types.
//
// Return values:
//   n>0    n barcodes found
//   0      no barcodes found
//  -1      barcode services not available.
//	-2		-not used-
//  -3      invalid or null image
//	-4		memory error (low memory?)
//  -5		internal error, or error from 3rd party barcode engine.

LPCSTR EZTAPI BARCODE_Text(int n);
// Return the text of the nth barcode recognized by the last BARCODE_Recognize.
// barcodes are numbered from 0.
// If there is any problem of any kind, returns the empty string.

BOOL EZTAPI BARCODE_GetText(int n, LPSTR Text);
// Get the text of the nth barcode recognized by the last BARCODE_Recognize.
// Please allow 64 characters in your text buffer.  Use a smaller buffer
// only if you *know* that the barcode type is limited to shorter strings.

int EZTAPI BARCODE_Type(int n);
// Return the type (symbology) of the nth barcode recognized.

BOOL EZTAPI BARCODE_GetRect(int n, double *L, double *T, double *R, double *B);
// Get the rectangle bounding the nth barcode found in the last BARCODE_Recognize.
// Returns TRUE(1) if successful, FALSE(0) otherwise.  The only likely cause
// of a FALSE return would be an invalid value of n, or a null reference.
// L    = left edge
// T    = top edge
// R    = right edge
// B    = bottom edge
// Note: Returned coordinates are in pixels, relative to the upper-left corner
// of the image given to BARCODE_Recognize.

//--------- OCR (Optical Character Recognition) -------

// Note: Requires the Transym OCR engine (TOCR) which must be separately
// licensed from Transym - See www.transym.com

BOOL EZTAPI OCR_IsAvailable(void);
// TRUE(1) if OCR recognition is available in some form.
// Returns FALSE(0) otherwise.

int EZTAPI OCR_Version(void);
// Returns version * 100 of the EZTwain OCR module.

// ----- OCR engines supported by EZTwain -----
#define EZOCR_ENGINE_NONE		0       // null engine, no OCR services.
#define EZOCR_ENGINE_TRANSYM	1       // Transym 'TOCR' engine

BOOL EZTAPI OCR_IsEngineAvailable(int nEngine);
BOOL EZTAPI OCR_SelectEngine(int nEngine);
int EZTAPI OCR_SelectedEngine(void);
BOOL EZTAPI OCR_SelectDefaultEngine(void);

LPCSTR EZTAPI OCR_EngineName(int nEngine);
// Returns the short name ("None", "Transym TOCR") of the specified
// engine, or the empty string if nEngine is not a recognized OCR engine code.

void EZTAPI OCR_SetEngineKey(LPCSTR pzKey);
// Set the license key to be passed to the OCR engine.
// * If you are using the reseller version of Transym's TOCR, pass the
//   RegNo provided by Transym, as a string e.g. "0123-4567-89AB-CDEF"

void EZTAPI OCR_SetLineBreak(LPCSTR pzEOL);
// Set the character sequence to use for line breaks in
// the returned OCR'd text (as returned by OCR_Text and OCR_GetText).
// ..
// The default OCR line break is \n (LF, 0x0A)
// Other commonly used line breaks are \r (CR, 0x0D) or CRLF.
// Set this *before* doing OCR - it does not modify already
// recognized text.

int EZTAPI OCR_RecognizeDib(HDIB hdib);
int EZTAPI OCR_RecognizeDibZone(HDIB hdib, int x, int y, int w, int h);
// Find and recognize text in the given image, or
// in a designated zone of an image.
// Coordinates are left pixel, top pixel, width & height in pixels.
//
// Return values:
//   0		no error, but no text found
//   n > 0	n characters found (including spaces and returns)
//  -1		OCR services not available
//  -3		invalid or null image
//  -5		internal error or error returned by OCR engine
//
// In case of error, call TWAIN_ReportLastError to display details,
// or call TWAIN_LastErrorCode and related functions.

LPCSTR EZTAPI OCR_Text(void);
// Return the text found by the last OCR_RecognizeDib
// If there is any problem of any kind, returns the empty string.

int EZTAPI OCR_GetText(LPSTR TextBuffer, int nBufLen);
// Read the text recognized by the last OCR_RecognizeDib
// into the TextBuffer, which is allocated to hold nBufLen chars.
// Returns the number of characters actually returned.
// Always appends a trailing 0 (NUL).
// Will return 0 if the available text does not fit.

int EZTAPI OCR_TextLength(void);
// Returns the number of characters in OCR_Text.
// Does not count the terminal NUL,
// for those of you working with C-style strings.

int EZTAPI OCR_TextOrientation(void);
// Returns the orientation of the text found by the last OCR_RecognizeDib.
// The value is the number of degrees clockwise that the input
// image was auto-rotated before OCR was performed.
// Currently, the returned value is always a multiple of 90, so
// the only possible values are 0, 90, 180 and 270.
// Example: If the original was turned 90 degrees clockwise before scanning,
// it will be auto-rotated 90 degrees *counter-clockwise* before OCR, so
// then the value of this function will be 270.

BOOL EZTAPI OCR_GetCharPositions(long charx[], long chary[]);
BOOL EZTAPI OCR_GetCharSizes(long charw[], long charh[]);
// Return the coordinates or sizes of the characters found by the last
// OCR_RecognizeDib call.
// For each character of the string returned by OCR_Text or OCR_GetText,
// these functions return the x and y coordinates in the array charx and chary,
// and the width and height in the arrays charw and charh.
// So (charx[i],chary[i]) will be the position of the ith character.
// Coordinates are for the top-left corner of the character, relative
// to the top-left corner of the OCR'd image.
// Width and height are in pixels.
//
// Please make *sure* that you pass in (the address/reference of)
// two arrays allocated to hold n values, where n is the return
// value from the last call to OCR_Recognize.

void EZTAPI OCR_GetResolution(double *xdpi, double *ydpi);
// Return the resolution (in DPI) of the last image given to OCR_RecognizeDib.
// Useful for translating pixel coordinates and sizes into physical (inch) values.

void EZTAPI OCR_ClearText(void);
// Clear any currently stored OCR text.

BOOL EZTAPI OCR_WritePage(HDIB hdib);
// If an OCR engine is selected and available, and there is
// a PDF file open for writing (by TWAIN_BeginMultipageFile), then
// this function OCRs the image, and writes both the image and
// the text to the output PDF.
//
// Returns TRUE if successful, FALSE otherwise:
// In case of error, call TWAIN_ReportLastError to display details,
// or call TWAIN_LastErrorCode and related functions.

BOOL EZTAPI OCR_WriteTextToPDF(void);
// Write the text from the last OCR to the next PDF page.
// Returns TRUE if successful, FALSE in case of error.
// If there is no OCR text to write, does nothing & returns TRUE.

void EZTAPI OCR_SetAutoRotatePagesToPDF(BOOL bYes);
BOOL EZTAPI OCR_GetAutoRotatePagesToPDF(void);
// Get/Get a global option 'Auto Rotate Pages to PDF' that affects
// output of OCR'd text and images to PDF.
//
// When this option is set, OCR_WritePage and OCR_WriteTextToPDF use the
// orientation of any OCR'd text to rotate each page so text is 'upright'.
// This requires rotating both the text and image on each affected page.
// Of course any functions that call those functions are also affected.

//--------- Fun With Containers --------

// Capability values are passed thru the TWAIN API in complex global
// memory structures called 'containers'.  EZTWAIN abstracts these
// containers with a handle (an integer) called an HCONTAINER.
// If you are coding in VB or similar, this is a 32-bit integer.
// The following functions provide reasonably comprehensive access
// to the contents of containers.  See also TWAIN_Get, TWAIN_Set.
//
// There are four shapes of containers, which I call 'formats'.
// Depending on its format, a container holds some 'items' - these
// are simple data values, all the same type in a given container.
// Item types are enumerated by TWTY_*

// Container formats, same codes as in TWAIN.H
#define TWON_ARRAY           3 // indicates TW_ARRAY container
#define TWON_ENUMERATION     4 // indicates TW_ENUMERATION container
#define TWON_ONEVALUE        5 // indicates TW_ONEVALUE container
#define TWON_RANGE           6 // indicates TW_RANGE container

#ifndef _XDEFS_
// Backward-compatible with EZTwain 2.x
#define CONTAINER_ARRAY           3
#define CONTAINER_ENUMERATION     4
#define CONTAINER_ONEVALUE        5
#define CONTAINER_RANGE           6
#endif

void EZTAPI CONTAINER_Free(HCONTAINER hcon);
// Free the memory and resources of a capability container.

HCONTAINER EZTAPI CONTAINER_Copy(HCONTAINER hcon);
// Create an exact copy of the container.

BOOL EZTAPI CONTAINER_Equal(HCONTAINER hconA, HCONTAINER hconB);
// Return TRUE (1) iff all properties of hconA and hconB are the same.

int EZTAPI CONTAINER_Format(HCONTAINER hcon);
// Return the 'format' of this container: TWON_ONEVALUE, etc.

int EZTAPI CONTAINER_ItemCount(HCONTAINER hcon);
// Return the number of values in the container.
// For a ONEVALUE, return 1.

int EZTAPI CONTAINER_ItemType(HCONTAINER hcon);
// Return the item type (what exact kind of values are in the container.)
// See the TWTY_* definitions in TWAIN.H

int EZTAPI CONTAINER_TypeSize(int nItemType);
// Return the size in bytes of an item of the specified type (TWTY_*)

void EZTAPI CONTAINER_GetStringValue(HCONTAINER hcon, int n, LPSTR pzText);
double EZTAPI CONTAINER_FloatValue(HCONTAINER hcon, int n);
int EZTAPI CONTAINER_IntValue(HCONTAINER hcon, int n);
LPCSTR EZTAPI CONTAINER_StringValue(HCONTAINER hcon, int n);
// Get the value of the nth item in the container.
// n is forced into the range 0 to ItemCount(hcon)-1.
// For string values, if the container items are not strings, they
// are converted to an equivalent string (e.g. "TRUE", "23", "2.37", etc.)

#ifndef _XDEFS_
BYTE* EZTAPI CONTAINER_ValuePtr(HCONTAINER hcon, int n);
// Return a pointer to the nth item in the container.
#endif

BOOL EZTAPI CONTAINER_ContainsValue(HCONTAINER hcon, double d);
BOOL EZTAPI CONTAINER_ContainsValueInt(HCONTAINER hcon, int n);
// Return TRUE(1) if the value is one of the items in the container.
int EZTAPI CONTAINER_FindValue(HCONTAINER hcon, double d);
int EZTAPI CONTAINER_FindValueInt(HCONTAINER hcon, int n);
// Return the 0-origin index of the value in the container.
// Return -1 if not found.

double EZTAPI CONTAINER_CurrentValue(HCONTAINER hcon);
double EZTAPI CONTAINER_DefaultValue(HCONTAINER hcon);
int EZTAPI CONTAINER_CurrentValueInt(HCONTAINER hcon);
int EZTAPI CONTAINER_DefaultValueInt(HCONTAINER hcon);
// Return the container's current or power-up (default) value.
// Array containers do not have these and will return -1.0.
// OneValue containers always return their (one) value.

int EZTAPI CONTAINER_DefaultIndex(HCONTAINER hcon);
int EZTAPI CONTAINER_CurrentIndex(HCONTAINER hcon);
// Return the index of the Default or Current value.
// Works on Enumerations, Ranges and OneValues.
// (Always returns 0 for a OneValue)
// Returns -1 for an Array.


double EZTAPI CONTAINER_MinValue(HCONTAINER hcon);
double EZTAPI CONTAINER_MaxValue(HCONTAINER hcon);
int EZTAPI CONTAINER_MinValueInt(HCONTAINER hcon);
int EZTAPI CONTAINER_MaxValueInt(HCONTAINER hcon);
// Return the smallest/largest value in the container.
// For a OneValue, this is just the value.
// For a Range, these are the Min and Max values of the range.
// For an Array or Enumeration, the container is searched to find
// the smallest/largest value.

double EZTAPI CONTAINER_StepSize(HCONTAINER hcon);
int EZTAPI CONTAINER_StepSizeInt(HCONTAINER hcon);
// Return the 'step' value of a Range container.
// Returns -1 if the container is not a Range.

// The following four functions create containers from scratch:
// nItemType is one of the TWTY_* item types from TWAIN.H
// nItems is the number of items, in an array or enumeration.
// dMin, dMax, dStep are the beginning, ending, and step value of a range.
HCONTAINER EZTAPI CONTAINER_OneValue(int nItemType, double dVal);
HCONTAINER EZTAPI CONTAINER_Range(int nItemType, double dMin, double dMax, double dStep);
HCONTAINER EZTAPI CONTAINER_Array(int nItemType, int nItems);
HCONTAINER EZTAPI CONTAINER_Enumeration(int nItemType, int nItems);

BOOL EZTAPI CONTAINER_SetItem(HCONTAINER hcon, int n, double dVal);
BOOL EZTAPI CONTAINER_SetItemInt(HCONTAINER hcon, int n, int nVal);
BOOL EZTAPI CONTAINER_SetItemString(HCONTAINER hcon, int n, LPCSTR pzVal);
BOOL EZTAPI CONTAINER_SetItemFrame(HCONTAINER hcon, int n, double l, double t, double r, double b);
BOOL EZTAPI CONTAINER_GetItemFrame(HCONTAINER hcon, int n, double *L, double *T, double *R, double *B);
// Set(or get) the nth item of the container to dVal or pzText, or frame(l,t,r,b).
// NOTE: A OneValue is treated as an array with 1 element. 
// Return TRUE(1) if successful. FALSE(0) for error such as:
//    The container is not an array, enumeration, or onevalue
//    n < 0 or n >= CONTAINER_ItemCount(hcon)
//    the value cannot be represented in this container's ItemType.
// Frame operations fail if the CONTAINER_ItemType is not TWTY_FRAME.

BOOL EZTAPI CONTAINER_SelectCurrentValue(HCONTAINER hcon, double dVal);
BOOL EZTAPI CONTAINER_SelectCurrentItem(HCONTAINER hcon, int n);
// Select the current value within an enumeration or range,
// by specifying either the value, or its index.
// Returns TRUE(1) if successful, FALSE(0) otherwise.
// This will fail if:
//    The container is not an enumeration or range.
//    dVal is not one of the values in the container
//    n < 0 or n >= CONTAINER_ItemCount(hcon)

BOOL EZTAPI CONTAINER_SelectDefaultValue(HCONTAINER hcon, double dVal);
BOOL EZTAPI CONTAINER_SelectDefaultItem(HCONTAINER hcon, int n);
// Select the default value in an enumeration or range.
// We're not sure what this would be good for, since an application
// cannot change the default value of a capability - that value is
// determined by the device TWAIN driver.
// So these functions are for logical completeness only.

BOOL EZTAPI CONTAINER_DeleteItem(HCONTAINER hcon, int n);
// Delete the nth item from an Array or Enumeration container.
// Returns TRUE(1) for success, FALSE(0) otherwise. Failure causes:
//   invalid container handle
//   container is not an array or enumeration
//   n < 0 or n >= ItemCount(hcon)

BOOL EZTAPI CONTAINER_InsertItem(HCONTAINER hcon, int n, double dVal);
// Insert an item with value dVal into the container at position n.
// If n < 0, the item is inserted at the end of the container.
// Return TRUE(1) on success, FALSE(0) on failure.
// Possible causes of failure:
//   NULL or invalid container handle
//   container format is not enumeration or array
//   memory allocation failed - heap corrupted, or out of memory.

//--- Very low level CONTAINER functions you probably won't need:
HCONTAINER EZTAPI CONTAINER_Wrap(int nFormat, HANDLE hcon);
// Wrap a TWAIN container handle into an HCONTAINER object.
// Note: *Do Not* free the hcon - it is now owned by the HCONTAINER.
HANDLE EZTAPI CONTAINER_Unwrap(HCONTAINER hcon);
// Unwrap a TWAIN container from an HCONTAINER object - free the
// HCONTAINER and return the original TWAIN container handle.
HANDLE EZTAPI CONTAINER_Handle(HCONTAINER hcon);
// Retrieve the handle of the TWAIN container wrapped in our HCONTAINER
BOOL EZTAPI CONTAINER_IsValid(HCONTAINER hcon);
// Return TRUE if the argument seems to be a valid HCONTAINER object.

//--------- Low-level Capability Negotiation Functions --------

// Setting a capability is valid only in State 4 (TWAIN_SOURCE_OPEN)
// Getting a capability is valid in State 4 or any higher state.

BOOL EZTAPI TWAIN_IsCapAvailable(unsigned uCap);
// Test if open device responds to a 'Get' on a capability.
// Only valid in State 4 or higher.
// Returns TRUE(1) if the capability can be queried, FALSE(0) if not.

HCONTAINER EZTAPI TWAIN_Get(unsigned uCap);
// Issue a DAT_CAPABILITY/MSG_GET to the open source.
// Return a capability 'container' - the 'MSG_GET' value of the capability.
// Use CONTAINER_* functions to examine and modify the container object.
// Use CONTAINER_Free to release it when you are done with it.
// A return value of 0 indicates failure:  Call GetConditionCode
// or ReportLastError above.

HCONTAINER EZTAPI TWAIN_GetDefault(unsigned uCap);
HCONTAINER EZTAPI TWAIN_GetCurrent(unsigned uCap);
// Issue a DAT_CAPABILITY/MSG_GETDEFAULT or MSG_GETCURRENT.  See Get above.

BOOL EZTAPI TWAIN_Set(unsigned uCap, HCONTAINER hcon);
// Issue a DAT_CAPABILITY/MSG_SET to the open source,
// using the specified capability and container.
// Return value as for TWAIN_DS

BOOL EZTAPI TWAIN_Reset(unsigned uCap);
// Issue a MSG_RESET on the specified capability.
// State must be 4.  Returns TRUE(1) if successful, FALSE(0) otherwise.

int EZTAPI TWAIN_QuerySupport(unsigned uCap);
// Issue a MSG_QUERYSUPPORT on the specified capability.
// State must be 4 or higher.  Returns the integer value that the device
// returned, which can be 0.
// A return < 0 indicates an error.

BOOL EZTAPI TWAIN_SetCapability(unsigned cap, double dValue);
// The most general capability-setting function, it negotiates
// with the open device to set the given capability to the specified value.
// If successful, returns TRUE(1), otherwise FALSE(0).
// There must be a device open and in state 4, or an error is recorded.
// (See TWAIN_ReportLastError.)

BOOL EZTAPI TWAIN_SetCapString(unsigned cap, LPCSTR pzValue);
// Set the value of a capability that takes a string value.
// You don't need to specify the 'itemType', EZTwain asks the driver
// which itemType it wants.

BOOL EZTAPI TWAIN_SetCapBool(unsigned cap, BOOL bValue);
// Shorthand for TWAIN_SetCapOneValue(cap, TWTY_BOOL, bValue);

BOOL EZTAPI TWAIN_GetCapBool(unsigned cap, BOOL bDefault);
double EZTAPI TWAIN_GetCapFix32(unsigned cap, double dDefault);
int EZTAPI TWAIN_GetCapUint16(unsigned cap, int nDefault);
long EZTAPI TWAIN_GetCapUint32(unsigned cap, long lDefault);
// Issue a DAT_CAPABILITY/MSG_GETCURRENT on the specified capability,
// assuming the value type is Bool, Fix32, etc..
// If successful, return the returned value.  Otherwise return bDefault.
// This is only valid in State 4 (TWAIN_SOURCE_OPEN) or higher.

BOOL EZTAPI TWAIN_SetCapFix32(unsigned Cap, double dVal);
BOOL EZTAPI TWAIN_SetCapOneValue(unsigned Cap,
                                 unsigned ItemType,
                                 long ItemVal);
// Do a DAT_CAPABILITY/MSG_SET, on capability 'Cap' (e.g. ICAP_PIXELTYPE,
// CAP_AUTOFEED, etc.) using a TW_ONEVALUE container with the given item type
// and value.  Use SetCapFix32 for capabilities that take a FIX32 value,
// use SetCapOneValue for the various ints and uints.  These functions
// do not support FRAME or STR items.
// Return Value: TRUE (1) if successful, FALSE (0) otherwise.

BOOL EZTAPI TWAIN_SetCapFix32R(unsigned Cap, int Numerator, int Denominator);
// Just like TWAIN_SetCapFix32, but uses the value Numerator/Denominator
// This is useful for languages that make it hard to pass double parameters.

BOOL EZTAPI TWAIN_GetCapCurrent(unsigned Cap,
                               unsigned ItemType,
                               LPVOID   pVal);
// Do a DAT_CAPABILITY/MSG_GETCURRENT on capability 'Cap'.
// Copy the current value out of the returned container into *pVal.
// If the operation fails (the source refuses the request), or if the
// container is not a ONEVALUE or ENUMERATION, or if the item type of the
// returned container is incompatible with the expected TWTY_ type in nType,
// returns FALSE.  If this function returns FALSE, *pVal is not touched.

long EZTAPI TWAIN_ToFix32(double d);
// Convert a floating-point value to a 32-bit TW_FIX32 value that can be passed
// to e.g. TWAIN_SetCapOneValue
long EZTAPI TWAIN_ToFix32R(int Numerator, int Denominator);
// Convert a rational number to a 32-bit TW_FIX32 value.
// Returns a TW_FIX32 value that approximates Numerator/Denominator

double EZTAPI TWAIN_Fix32ToFloat(long nfix);
// Convert a TW_FIX32 value (as returned from some capability inquiries)
// to a double (floating point) value.


//--------- Custom DS Data
//
// The following functions support the CUSTOMDSDATA feature
// introduced in TWAIN 1.7.  This is an optional feature - many document
// scanners support it, and some flatbeds.  It allows an application to
// capture a snapshot of a particular device's settings, and then to restore
// that state at a later time.  It is particularly useful in conjunction
// with TWAIN_DoSettingsDialog, q.v.
//
// Note: The format of the custom data is not defined or restricted by TWAIN
// so typically differs between vendors and even between scanner models.
// It is also *not* restricted to be ANSI text, although most vendors seem to
// use a text format.
//
// To find out if a device supports this feature, open the device and see if
// TWAIN_GetCapBool(CAP_CUSTOMDSDATA, FALSE) returns TRUE.
//
// These are valid only in TWAIN_State() = 4 (TWAIN_SOURCE_OPEN)
//
BOOL EZTAPI TWAIN_GetCustomDataToFile(LPCSTR pzFilename);
BOOL EZTAPI TWAIN_SetCustomDataFromFile(LPCSTR pzFilename);
// Get or Set the 'custom data' of the currently open device, if supported,
// by writing it to, or reading it from, a file.
//
// If the device supports it, Get will save the entire settings-state of
// the device into the file. Set will restore all settings of the device
// from those saved in the file.
//
// Both functions return TRUE(1) if successful, FALSE(0) otherwise.
// These functions record an error and return FALSE if called outside State 4.
// In case of failure, call LastErrorCode, ReportLastError, etc. for details.
// No file extension is assumed, you should provide one, such as ".dat".

BOOL EZTAPI TWAIN_SetCustomData(const BYTE* data, long nbytes);
// Same as TWAIN_SetCustomDataFromFile, but from a buffer in memory.

int EZTAPI TWAIN_GetCustomData(BYTE* buffer, long bufsize);
// Read device custom data into a buffer in memory, up to bufsize bytes.
// Returns the size of the actual data, if successful.
// Returns 0 if the device doesn't support this, no device open, etc.

LPCSTR EZTAPI TWAIN_CustomData(void);
// Reads the custom data from the device and returns a pointer to it.
// This works best if you know the custom data is 8-bit text.

//--------- Extended Image Info
//
// The following functions support the 'Extended Image Info' feature of TWAIN,
// which is implemented by only a few TWAIN drivers.  This consists of special
// information, sometimes called 'metadata' which can be collected about
// each scanned image, in addition to the image itself.
// Examples of extended image info include
// TWEI_BARCODETEXT - text of a barcode found in the scan
// TWEI_SKEWORIGINALANGLE - the amount of 'skew' in the original raw scan
// See the TWAIN Specification (version 1.9 or later) for details.

BOOL EZTAPI TWAIN_IsExtendedInfoSupported(void);
// Asks the currently open device if it supports Extended Image Info.
// Returns TRUE(1) if yes, FALSE(0) if not.

BOOL EZTAPI TWAIN_EnableExtendedInfo(long eiCode, BOOL enabled);
// Enable or disable collection of a particular kind of extended image info.
// Each type of information is represented by an integer constant with
// prefix TWEI_ see the list of constants elsewhere in this file.
// There is a limit to how many different info types can be enabled at the
// same time.  If this limit is exceeded, this function returns FALSE
// and has no effect.  Otherwise (if successful) it returns TRUE.

BOOL EZTAPI TWAIN_IsExtendedInfoEnabled(long eiCode);
// Return TRUE if the specified extended image type is enabled
// (for collection)

void EZTAPI TWAIN_DisableExtendedInfo(void);
// Disables all extended image info - none is collected after this.

// After a successful scan, you can use the following functions to
// retrieve the extended image info associated with that scan:
long EZTAPI TWAIN_ExtendedInfoItemCount(long eiCode);
// Return the number of items of data available of the given info type.

long EZTAPI TWAIN_ExtendedInfoItemType(long eiCode);
// Return a number indicating the type of data returned for the specified extended info.
// Returns the same TWTY_ codes as CONTAINER_ItemType.

long EZTAPI TWAIN_ExtendedInfoInt(long eiCode, long n);
// Return the (integer) value of the 'nth' item of the specified extended info.

double EZTAPI TWAIN_ExtendedInfoFloat(long eiCode, long n);
// Return the (floating point) value of the 'nth' item of the specified extended info.

BOOL EZTAPI TWAIN_GetExtendedInfoString(long eiCode, long n, LPSTR Buffer, long Bufsize);
// Read the (string) value of the nth item of the specified info type into Buffer,
// which has been allocated by the caller to hold Bufsize characters.
// Note that the value returned is ASCII (byte) text, not unicode, and *always*
// includes an ending 0 byte, even if it must be truncated to fit.
// Returns TRUE if the data was retrieved and could fit in the buffer.
// Returns FALSE otherwise.

LPCSTR EZTAPI TWAIN_ExtendedInfoString(long eiCode, long n);
// As above, but the string is returned as a temporary pointer to a
// 0-terminated ASCII string.
// In case of any failure, returns the empty string ("").

BOOL EZTAPI TWAIN_GetExtendedInfoFrame(long eiCode, long n, double *L, double *T, double *R, double *B);
// Fetch the TW_FRAME value of the 'nth' item of the specified extended info.
// This is rarely used, but is here for completeness.

// Extended Image Info codes
#define TWEI_MIN                    0x1200

#define TWEI_BARCODEX               0x1200
#define TWEI_BARCODEY               0x1201
#define TWEI_BARCODETEXT            0x1202
#define TWEI_BARCODETYPE            0x1203
#define TWEI_DESHADETOP             0x1204
#define TWEI_DESHADELEFT            0x1205
#define TWEI_DESHADEHEIGHT          0x1206
#define TWEI_DESHADEWIDTH           0x1207
#define TWEI_DESHADESIZE            0x1208
#define TWEI_SPECKLESREMOVED        0x1209
#define TWEI_HORZLINEXCOORD         0x120A
#define TWEI_HORZLINEYCOORD         0x120B
#define TWEI_HORZLINELENGTH         0x120C
#define TWEI_HORZLINETHICKNESS      0x120D
#define TWEI_VERTLINEXCOORD         0x120E
#define TWEI_VERTLINEYCOORD         0x120F
#define TWEI_VERTLINELENGTH         0x1210
#define TWEI_VERTLINETHICKNESS      0x1211
#define TWEI_PATCHCODE              0x1212
#define TWEI_ENDORSEDTEXT           0x1213
#define TWEI_FORMCONFIDENCE         0x1214
#define TWEI_FORMTEMPLATEMATCH      0x1215
#define TWEI_FORMTEMPLATEPAGEMATCH  0x1216
#define TWEI_FORMHORZDOCOFFSET      0x1217
#define TWEI_FORMVERTDOCOFFSET      0x1218
#define TWEI_BARCODECOUNT           0x1219
#define TWEI_BARCODECONFIDENCE      0x121A
#define TWEI_BARCODEROTATION        0x121B
#define TWEI_BARCODETEXTLENGTH      0x121C
#define TWEI_DESHADECOUNT           0x121D
#define TWEI_DESHADEBLACKCOUNTOLD   0x121E
#define TWEI_DESHADEBLACKCOUNTNEW   0x121F
#define TWEI_DESHADEBLACKRLMIN      0x1220
#define TWEI_DESHADEBLACKRLMAX      0x1221
#define TWEI_DESHADEWHITECOUNTOLD   0x1222
#define TWEI_DESHADEWHITECOUNTNEW   0x1223
#define TWEI_DESHADEWHITERLMIN      0x1224
#define TWEI_DESHADEWHITERLAVE      0x1225
#define TWEI_DESHADEWHITERLMAX      0x1226
#define TWEI_BLACKSPECKLESREMOVED   0x1227
#define TWEI_WHITESPECKLESREMOVED   0x1228
#define TWEI_HORZLINECOUNT          0x1229
#define TWEI_VERTLINECOUNT          0x122A
#define TWEI_DESKEWSTATUS           0x122B
#define TWEI_SKEWORIGINALANGLE      0x122C
#define TWEI_SKEWFINALANGLE         0x122D
#define TWEI_SKEWCONFIDENCE         0x122E
#define TWEI_SKEWWINDOWX1           0x122F
#define TWEI_SKEWWINDOWY1           0x1230
#define TWEI_SKEWWINDOWX2           0x1231
#define TWEI_SKEWWINDOWY2           0x1232
#define TWEI_SKEWWINDOWX3           0x1233
#define TWEI_SKEWWINDOWY3           0x1234
#define TWEI_SKEWWINDOWX4           0x1235
#define TWEI_SKEWWINDOWY4           0x1236
#define TWEI_BOOKNAME               0x1238  /* added 1.9 */
#define TWEI_CHAPTERNUMBER          0x1239  /* added 1.9 */
#define TWEI_DOCUMENTNUMBER         0x123A  /* added 1.9 */
#define TWEI_PAGENUMBER             0x123B  /* added 1.9 */
#define TWEI_CAMERA           	    0x123C  /* added 1.9 */
#define TWEI_FRAMENUMBER            0x123D  /* added 1.9 */
#define TWEI_FRAME	                0x123E  /* added 1.9 */
#define TWEI_PIXELFLAVOR            0x123F  /* added 1.9 */
#define TWEI_ICCPROFILE             0x1240  /* added 1.91 */
#define TWEI_LASTSEGMENT            0x1241  /* added 1.91 */
#define TWEI_SEGMENTNUMBER          0x1242  /* added 1.91 */
#define TWEI_MAGDATA                0x1243  /* added 2.0 */
#define TWEI_MAGTYPE                0x1244  /* added 2.0 */
#define TWEI_PAGESIDE               0x1245
#define TWEI_FILESYSTEMSOURCE       0x1246

#define TWEI_MAX                    0x1246


//--------- Lowest-level functions for TWAIN protocol --------


BOOL EZTAPI TWAIN_DS(unsigned long DG, unsigned DAT, unsigned MSG, LPVOID pData);
// Pass the triplet (DG, DAT, MSG, pData) to the open data source if any.
// Returns TRUE(1) if the result code is TWRC_SUCCESS, FALSE(0) otherwise.
// The last result code can be retrieved with TWAIN_GetResultCode(), and the
// corresponding condition code can be retrieved with TWAIN_GetConditionCode().
// If no source is open this call will fail, result code TWRC_FAILURE,
// condition code TWCC_NODS.

BOOL EZTAPI TWAIN_Mgr(unsigned long DG, unsigned DAT, unsigned MSG, LPVOID pData);
// Pass a triplet to the Data Source Manager (DSM).
// Returns TRUE(1) for success, FALSE(0) otherwise.
// See GetResultCode, GetConditionCode, and ReportLastError functions
// for diagnosing and reporting a TWAIN_Mgr failure.
// If the Source Manager is not open, this call fails setting result code
// TWRC_FAILURE, and condition code=TWCC_SEQERROR (triplet out of sequence).


//--------- Advanced / Exotic --------

// Functions to do a memory transfer in individual blocks:
BOOL EZTAPI TWAIN_BeginAcquireMemory(HWND hwnd, int nRows);
// Begin a memory transfer.
// Returns TRUE(1) if the transfer is ready to proceed (using
// TWAIN_AcquireMemoryBlock, below.)
// Returns FALSE(0) if the transfer could not be started for some reason.
//
// Loads TWAIN if necessary, opens the default source if no source is open.
// If it opens a source, it negotiates any 'pending' settings (resolution,
// pixel type, etc.) that were specified before the device was open.
// Enables the device if not already enabled.
// Waits for a 'transfer ready' message from the device.
// Tells the driver to begin transferring in blocks of nRows rows or less.
// If nRows is <= 0, lets the driver pick the optimal block size.

HANDLE EZTAPI TWAIN_AcquireMemoryBlock(void);
// Acquire the next block of data in a memory transfer.
// If there is an error or there is no more data, returns NULL(0).
// Only valid after a successful call to TWAIN_BeginAcquireMemory (above.)
// Asks the device to deliver another block of pixels, and returns
// those pixels as a DIB represented by its handle.  This is the same
// image format returned by TWAIN_Acquire, TWAIN_AcquireMemory, etc.
// See the DIB_* functions for what can be done with the returned handle.

BOOL EZTAPI TWAIN_EndAcquireMemory(void);
// Clean up after a block-by-block memory transfer.
// Only valid after a successful call to TWAIN_BeginAcquireMemory (above.)
// Frees any temporary storage, and tells the device the transfer
// is over.  In Multi-transfer mode, the device will move to
// State 6 if more images are available, or State 5 if not.
// In single-transfer mode (the default) the device is automatically closed.

#ifndef _XDEFS_
// Don't even try to translate callbacks into other languages

typedef BOOL (WINAPI *MEMXFERCALLBACK)(LPVOID data);

BOOL EZTAPI TWAIN_AcquireMemoryCallback(HWND hwnd, MEMXFERCALLBACK cb, LPVOID data);
// Like TWAIN_AcquireMemory, but you provide a call-back function.
// The call-back is called when the transfer is ready, and is responsible for
// setting up the transfer, transferring the data, and doing clean-up.
// See the function MemoryXferHandler in EZTWAIN.C for an example.

#endif

BOOL EZTAPI TWAIN_AcquireFile(HWND hwndApp, int nFF, LPCSTR pzFileName);
// Acquire an image directly to a file using File Transfer Mode.
// Be warned: File Transfer Mode is unusual. TWAIN drivers are not required
// to support it! If they do support it, the only required file format is BMP.
// We recommend not using this function unless you understand the issues
// and have a compelling reason for using this mode.
//
//---- Aliases for TWAIN File Formats
#define TWAIN_FF_TIFF        0    /* Tagged Image File Format     */
#define TWAIN_FF_PICT        1    /* Macintosh PICT               */
#define TWAIN_FF_BMP         2    /* Windows Bitmap               */
#define TWAIN_FF_XBM         3    /* X-Windows Bitmap             */
#define TWAIN_FF_JFIF        4    /* JPEG File Interchange Format */
#define TWAIN_FF_FPX         5    /* Flash Pix                    */
#define TWAIN_FF_TIFFMULTI   6    /* Multi-page tiff file         */
#define TWAIN_FF_PNG         7
#define TWAIN_FF_SPIFF       8
#define TWAIN_FF_EXIF        9
#define TWAIN_FF_PDF        10    /* 1.91 NB: this is not PDF/A */
#define TWAIN_FF_JP2        11    /* 1.91 */
#define TWAIN_FF_JPN        12    /* 1.91 */
#define TWAIN_FF_JPX        13    /* 1.91 */
#define TWAIN_FF_DEJAVU     14    /* 1.91 */
#define TWAIN_FF_PDFA       15    /* 2.0 */
//
// * Unlike AcquireToFilename, this function uses TWAIN File Transfer Mode.
// * The image is written to disk by the Data Source, not by EZTWAIN.
// * Warning: This mode is -not- supported by all TWAIN devices.
// 
// Use TWAIN_SupportsFileXfer to see if the open DS supports File Transfer.
//
// You can use TWAIN_Get(ICAP_IMAGEFILEFORMAT) to get an enumeration of
// the available file formats, and CONTAINER_ContainsValue to check for
// a particular format you are interested in.
//
// If the filename is NULL or an empty string, this functions prompts for
// the file name in a standard Save File dialog.
//
// Note Boolean return value!
//  TRUE(1) for success
//  FALSE(0) for failure - use GetResultCode/GetConditionCode for details.
//  If the user cancels the Save File dialog, GetResultCode will be TWRC_CANCEL

int EZTAPI TWAIN_SetImageReadyTimeout(int nSec);
// Set the maximum seconds to wait for an image-ready notification,
// (when one is expected i.e. after an enable) before posting a
// dialog that says 'Waiting for <device>' - with a Cancel button.
// Returns the previous setting.
// ** Default is -1 which disables this feature.
// With certain scanners there is a long delay between when the scanner
// is enabled and when it says "ready to scan".  Also, we have found
// a few scanners that intermittently fail to send "ready to scan" - by
// setting this timeout, you give your users a way to recover from
// this failure (otherwise the application has to be forcibly terminated.)

void EZTAPI TWAIN_AutoClickButton(LPCSTR pzButtonName);
// Calling this function before scanning tells EZTwain to attempt to
// automatically press a button when the device dialog appears.
// If you pass a null button name, EZTwain tries a number
// of likely choices (in English) including:
// "Scan" "Capture" "Acquire" "Scan Now" "Start Scan"  "Start Scanning"
// Case is ignored in the comparison ("SCAN" and "scan" are equivalent.)
// This function is useful when you want to automate operation of
// a device that insists on showing its user interface. 

void EZTAPI TWAIN_BreakModalLoop(void);
// Expert: If EZTwain is hung inside an Acquire or GetMessage loop waiting for
// something to happen, this function will break the loop, as if the pending
// transfer had failed.  TWAIN_State() will be valid, and you will need to
// call appropriate functions to transition TWAIN as desired.

void EZTAPI TWAIN_EmptyMessageQueue(void);
// Expert: Get and process any pending Windows messages for this thread.
// For example, keystrokes or mouse clicks.  Calling this during
// long processes will allow the user to interact with the UI.
// Use only if you understand the message pump.

//--------- Dosadi Special --------

LPCSTR EZTAPI TWAIN_BuildName(void);
// Return a string describing the build of EZTWAIN e.g. "Release - Build 6"

void EZTAPI TWAIN_GetBuildName(LPSTR pzName);
// Like TWAIN_BuildName, but copies the build string into its parameter.
// The parameter is a string variable (char array in C/C++).
// You are responsible for allocating room for 128 8-bit characters
// in the string variable before calling this function.

int EZTAPI TWAIN_GetSourceIdentity(LPVOID ptwid);

int EZTAPI TWAIN_GetImageInfo(LPVOID ptwinfo);
// Issue a DG_IMAGE / DAT_IMAGEINFO / MSG_GET placing the returned data
// at ptwinfo.  The returned structure is a TW_IMAGEINFO - see twain.h.

void EZTAPI TWAIN_LogFile(int fLog);
// Turn logging eztwain.log on or off.
// By default the log file is written to C:\ but this
// can be overridden, see TWAIN_SetLogFolder below.
//
// fLog = 0    close log file and turn off logging
// The following flags can be combined to enable logging:
// 1            basic logging of TWAIN and EZTwain operations.
// 2            flush log constantly (use if EZTwain crashes)
// 4            log Windows messages flowing through EZTwain
#define EZT_LOG_ON      1
#define EZT_LOG_FLUSH   2
#define EZT_LOG_DETAIL  4


BOOL EZTAPI TWAIN_SetLogFolder(LPCSTR pzFolder);
// Specify the folder (directory) where the log file
// should be placed.  Default is "c:\" - the root of the C: drive.
// EZTwain appends a trailing 'slash' if needed.
// Passing NULL or "" resets to the default: "c:\"
//
// If the file cannot be created in this folder, EZTwain tries
// to create it in the Windows temp folder - this varies somewhat
// by Windows version, search for the Windows API call GetTempPath.

BOOL EZTAPI TWAIN_SetLogName(LPCSTR pzName);
// Set the filename or path & filename of the EZTwain log file.
// If there is a log file open, it is closed, renamed & re-opened.
// The default extension is ".log".
// The default log filename is "eztwain.log".
//
// You can specify a fully-qualified filename, which changes
// both the folder and filename for logging:
// TWAIN_SetLogName("c:\temp\scan2tape.log")

LPCSTR EZTAPI TWAIN_LogFileName(void);
// Return the (fully qualified) file path and name for logging.

void EZTAPI TWAIN_WriteToLog(LPCSTR pzText);
// Write text to the EZTwain log file (c:\eztwain.log)
// If the text does not end with a newline, one is supplied.
// If logging is turned off, this call has no effect.
// Logging is controlled by TWAIN_LogFile - see above.


int EZTAPI TWAIN_SelfTest(unsigned f);
// Perform internal self-test.
//   f      ignored for now
// Return value:
//   0      success
//   other  internal test failed.

BOOL EZTAPI TWAIN_Blocked(void);
// Returns TRUE(1) if processing is inside TWAIN (Source Manager or a DS)
// FALSE(0) otherwise.  If the former, making any TWAIN call will
// fail immediately or deadlock the application (Not recommended.)

#ifndef _XDEFS_
// Definitions that are only exported to C
BSTR EZTAPI CONTAINER_StringValueVB(HCONTAINER hcon, int i);
BSTR EZTAPI TWAIN_BuildNameVB(void);
BSTR EZTAPI TWAIN_DefaultSourceNameVB(void);
BSTR EZTAPI TWAIN_NextSourceNameVB(void);
BSTR EZTAPI TWAIN_SourceNameVB(void);
BSTR EZTAPI TWAIN_LastErrorTextVB(void);
BSTR EZTAPI BARCODE_TypeNameVB(int nType);
BSTR EZTAPI BARCODE_EngineNameVB(int nEngine);
BSTR EZTAPI BARCODE_TextVB(int n);
BSTR EZTAPI DIB_PrinterNameVB(int i);
BSTR EZTAPI TWAIN_ExtendedInfoStringVB(long eiCode, long n);
BSTR EZTAPI UPLOAD_ResponseVB(void);
BSTR EZTAPI TWAIN_ExtensionFromFormatVB(int nFF, LPCSTR pzDefExt);
BSTR EZTAPI TWAIN_TiffTagAsciiVB(LPCSTR filename, int page, int tag);
BSTR EZTAPI TWAIN_LogFileNameVB(void);
BSTR EZTAPI OCR_EngineNameVB(int nEngine);
BSTR EZTAPI OCR_TextVB(void);
BSTR EZTAPI DOC_FilenameVB(HDOC hdoc);
BSTR EZTAPI PDF_DocumentPropertyVB(LPCSTR pzFilename, LPCSTR pzProperty);
//
// The following calls are only for use only by statically-linked applications.
// See the User Guide.pdf for instructions on linking to EZTwain statically.
//
extern int EZTWAIN_Attach();
// Initialize statically-linked EZTwain
extern int EZTWAIN_Detach();
// Terminate statically-linked EZTwain
// Does NOT replace a call to TWAIN_Shutdown - call that first!

void EZTWAIN_Log(LPCSTR pzMsg, ...);
// Write to the log file (if one is open) - treating the first parameter
// as a format string for any following parameters.

BOOL EZTAPI TWAIN_ProcessEvent(LPMSG lpmsg, int *ptwMsg);

#ifdef _EXTP_PRODUCT
extern char  szProductName[128];    // user-friendly name of product
extern char  szProductVersion[32];	// version of named product
#endif

#endif

// ----------------------------------------------------
// Deprecated - still work, don't use in new code.
// ----------------------------------------------------

void EZTAPI TWAIN_FreeNative(HDIB hdib);
// superceded by DIB_Free.

BOOL EZTAPI TWAIN_NegotiatePixelTypes(unsigned wPixMask);
// Legacy function
// Negotiate a set of acceptable pixel types.
//
// The parameter is a bit-mask - set bit N to allow pixel type N.
// Important: You cannot use the TWPT_ constants for the parameter, those
// are not bit-masks!  In other words, to tell the scanner you will accept
// only grayscale or color images, in C/C++ you write something like this:
//
//    TWAIN_NegotiatePixelTypes((1 << TWPT_BW) | (1 << TWPT_GRAY));
//
// See TWAIN_AcquireNative for more details.
//
// Note: Instead of using this function, most developers use
// TWAIN_SetPixelType to designate a single pixel type.


HDIB EZTAPI TWAIN_AcquireNative(HWND hwndApp, unsigned wPixMask);
// Legacy function, superceded by TWAIN_Acquire, TWAIN_AcquireToFilename, etc.
// Acquire one image from the currently open or default scanner.
//
// Parameter 1 is a Windows window-handle, the handle of the window that
// should own or be the parent of the TWAIN interaction.
// NULL(0) can be used if it is not convenient to obtain a valid window handle.
//
// Parameter 2 specifies a *pixel type mask*, as used with
// Most developers pass 0 for this parameter, and either allow the user
// to select the pixel type, or make an earlier call to TWAIN_SetPixelType
// to select the pixel type for scanning.
//
// In the pixel mask, set bit N to allow pixel type N.
// Bit 0 is the least-significant bit.
// Pixel Type constant          value     equiv. PixMask value
// TWPT_BW (black & white)        0               1
// TWPT_GRAY (grayscale)          1               2
// TWPT_RGB (RGB color)           2               4
// TWPT_PALETTE (indexed color)   3               8
// Since the parameter is a mask, you can add or 'or' together mask values
// to represent a set of more than one acceptable pixel type.

HDIB EZTAPI TWAIN_AcquireMemory(HWND hwnd);
// Same as TWAIN_Acquire but prefers to use 'memory transfer mode'.
// Equivalent to calling TWAIN_Acquire after calling TWAIN_SetXferMech(XFERMECH_MEMORY)
//
// It is better to use the general scanning functions like TWAIN_Acquire,
// and use TWAIN_SetXferMech to force memory transfer in the rare case
// that this solves a problem for an end-user.
// Note that EZTwain automatically uses memory transfer mode when appropriate,
// such as with scanner models known to require it for correct operation,
// so the only field problem should occur with a scanner not previously
// known to EZTwain, that malfunctions with our default handling.

BOOL EZTAPI TWAIN_AcquireToClipboard(HWND hwndApp, unsigned wPixMask);
// Like AcquireNative, but puts the resulting image, if any, into the
// system clipboard as a CF_DIB item. If this call fails, the clipboard is
// either empty or retains its previous content.
// Returns TRUE(1) for success, FALSE(0) for failure.
// 2nd parameter is a pixel type mask - See NegotiatePixelTypes above.
//
// Useful for environments like Visual Basic where it is hard to make direct
// use of a DIB handle.  In fact, TWAIN_AcquireToClipboard uses
// TWAIN_AcquireNative for all the hard work.



// From twain.h:
//****************************************************************************
//* Capabilities                                                             *
//****************************************************************************

#define CAP_CUSTOMBASE          0x8000 /* Base of custom capabilities */

/* all data sources are REQUIRED to support these caps */
#define CAP_XFERCOUNT           0x0001

/* image data sources are REQUIRED to support these caps */
#define ICAP_COMPRESSION        0x0100
#define ICAP_PIXELTYPE          0x0101
#define ICAP_UNITS              0x0102 /* default is TWUN_INCHES */
#define ICAP_XFERMECH           0x0103

/* all data sources MAY support these caps */
#define CAP_AUTHOR                  0x1000
#define CAP_CAPTION                 0x1001
#define CAP_FEEDERENABLED           0x1002
#define CAP_FEEDERLOADED            0x1003
#define CAP_TIMEDATE                0x1004
#define CAP_SUPPORTEDCAPS           0x1005
#define CAP_EXTENDEDCAPS            0x1006
#define CAP_AUTOFEED                0x1007
#define CAP_CLEARPAGE               0x1008
#define CAP_FEEDPAGE                0x1009
#define CAP_REWINDPAGE              0x100a
#define CAP_INDICATORS              0x100b   /* Added 1.1 */
#define CAP_SUPPORTEDCAPSEXT        0x100c   /* Added 1.6 */
#define CAP_PAPERDETECTABLE         0x100d   /* Added 1.6 */
#define CAP_UICONTROLLABLE          0x100e   /* Added 1.6 */
#define CAP_DEVICEONLINE            0x100f   /* Added 1.6 */
#define CAP_AUTOSCAN                0x1010   /* Added 1.6 */
#define CAP_THUMBNAILSENABLED       0x1011   /* Added 1.7 */
#define CAP_DUPLEX                  0x1012   /* Added 1.7 */
#define CAP_DUPLEXENABLED           0x1013   /* Added 1.7 */
#define CAP_ENABLEDSUIONLY          0x1014   /* Added 1.7 */
#define CAP_CUSTOMDSDATA            0x1015   /* Added 1.7 */
#define CAP_ENDORSER                0x1016   /* Added 1.7 */
#define CAP_JOBCONTROL              0x1017   /* Added 1.7 */
#define CAP_ALARMS                  0x1018   /* Added 1.8 */
#define CAP_ALARMVOLUME             0x1019   /* Added 1.8 */
#define CAP_AUTOMATICCAPTURE        0x101a   /* Added 1.8 */
#define CAP_TIMEBEFOREFIRSTCAPTURE  0x101b   /* Added 1.8 */
#define CAP_TIMEBETWEENCAPTURES     0x101c   /* Added 1.8 */
#define CAP_CLEARBUFFERS            0x101d   /* Added 1.8 */
#define CAP_MAXBATCHBUFFERS         0x101e   /* Added 1.8 */
#define CAP_DEVICETIMEDATE          0x101f   /* Added 1.8 */
#define CAP_POWERSUPPLY             0x1020   /* Added 1.8 */
#define CAP_CAMERAPREVIEWUI         0x1021   /* Added 1.8 */
#define CAP_DEVICEEVENT             0x1022   /* Added 1.8 */
#define CAP_SERIALNUMBER            0x1024   /* Added 1.8 */
#define CAP_PRINTER                 0x1026   /* Added 1.8 */
#define CAP_PRINTERENABLED          0x1027   /* Added 1.8 */
#define CAP_PRINTERINDEX            0x1028   /* Added 1.8 */
#define CAP_PRINTERMODE             0x1029   /* Added 1.8 */
#define CAP_PRINTERSTRING           0x102a   /* Added 1.8 */
#define CAP_PRINTERSUFFIX           0x102b   /* Added 1.8 */
#define CAP_LANGUAGE                0x102c   /* Added 1.8 */
#define CAP_FEEDERALIGNMENT         0x102d   /* Added 1.8 */
#define CAP_FEEDERORDER             0x102e   /* Added 1.8 */
#define CAP_REACQUIREALLOWED        0x1030   /* Added 1.8 */
#define CAP_BATTERYMINUTES          0x1032   /* Added 1.8 */
#define CAP_BATTERYPERCENTAGE       0x1033   /* Added 1.8 */
 
/* image data sources MAY support these caps */
#define ICAP_AUTOBRIGHT                   0x1100
#define ICAP_BRIGHTNESS                   0x1101
#define ICAP_CONTRAST                     0x1103
#define ICAP_CUSTHALFTONE                 0x1104
#define ICAP_EXPOSURETIME                 0x1105
#define ICAP_FILTER                       0x1106
#define ICAP_FLASHUSED                    0x1107
#define ICAP_GAMMA                        0x1108
#define ICAP_HALFTONES                    0x1109
#define ICAP_HIGHLIGHT                    0x110a
#define ICAP_IMAGEFILEFORMAT              0x110c
#define ICAP_LAMPSTATE                    0x110d
#define ICAP_LIGHTSOURCE                  0x110e
#define ICAP_ORIENTATION                  0x1110
#define ICAP_PHYSICALWIDTH                0x1111
#define ICAP_PHYSICALHEIGHT               0x1112
#define ICAP_SHADOW                       0x1113
#define ICAP_FRAMES                       0x1114
#define ICAP_XNATIVERESOLUTION            0x1116
#define ICAP_YNATIVERESOLUTION            0x1117
#define ICAP_XRESOLUTION                  0x1118
#define ICAP_YRESOLUTION                  0x1119
#define ICAP_MAXFRAMES                    0x111a
#define ICAP_TILES                        0x111b
#define ICAP_BITORDER                     0x111c
#define ICAP_CCITTKFACTOR                 0x111d
#define ICAP_LIGHTPATH                    0x111e
#define ICAP_PIXELFLAVOR                  0x111f
#define ICAP_PLANARCHUNKY                 0x1120
#define ICAP_ROTATION                     0x1121
#define ICAP_SUPPORTEDSIZES               0x1122
#define ICAP_THRESHOLD                    0x1123
#define ICAP_XSCALING                     0x1124
#define ICAP_YSCALING                     0x1125
#define ICAP_BITORDERCODES                0x1126
#define ICAP_PIXELFLAVORCODES             0x1127
#define ICAP_JPEGPIXELTYPE                0x1128
#define ICAP_TIMEFILL                     0x112a
#define ICAP_BITDEPTH                     0x112b
#define ICAP_BITDEPTHREDUCTION            0x112c  /* Added 1.5 */
#define ICAP_UNDEFINEDIMAGESIZE           0x112d  /* Added 1.6 */
#define ICAP_IMAGEDATASET                 0x112e  /* Added 1.7 */
#define ICAP_EXTIMAGEINFO                 0x112f  /* Added 1.7 */
#define ICAP_MINIMUMHEIGHT                0x1130  /* Added 1.7 */
#define ICAP_MINIMUMWIDTH                 0x1131  /* Added 1.7 */
#define ICAP_FLIPROTATION                 0x1136  /* Added 1.8 */
#define ICAP_BARCODEDETECTIONENABLED      0x1137  /* Added 1.8 */
#define ICAP_SUPPORTEDBARCODETYPES        0x1138  /* Added 1.8 */
#define ICAP_BARCODEMAXSEARCHPRIORITIES   0x1139  /* Added 1.8 */
#define ICAP_BARCODESEARCHPRIORITIES      0x113a  /* Added 1.8 */
#define ICAP_BARCODESEARCHMODE            0x113b  /* Added 1.8 */
#define ICAP_BARCODEMAXRETRIES            0x113c  /* Added 1.8 */
#define ICAP_BARCODETIMEOUT               0x113d  /* Added 1.8 */
#define ICAP_ZOOMFACTOR                   0x113e  /* Added 1.8 */
#define ICAP_PATCHCODEDETECTIONENABLED    0x113f  /* Added 1.8 */
#define ICAP_SUPPORTEDPATCHCODETYPES      0x1140  /* Added 1.8 */
#define ICAP_PATCHCODEMAXSEARCHPRIORITIES 0x1141  /* Added 1.8 */
#define ICAP_PATCHCODESEARCHPRIORITIES    0x1142  /* Added 1.8 */
#define ICAP_PATCHCODESEARCHMODE          0x1143  /* Added 1.8 */
#define ICAP_PATCHCODEMAXRETRIES          0x1144  /* Added 1.8 */
#define ICAP_PATCHCODETIMEOUT             0x1145  /* Added 1.8 */
#define ICAP_FLASHUSED2                   0x1146  /* Added 1.8 */
#define ICAP_IMAGEFILTER                  0x1147  /* Added 1.8 */
#define ICAP_NOISEFILTER                  0x1148  /* Added 1.8 */
#define ICAP_OVERSCAN                     0x1149  /* Added 1.8 */
#define ICAP_AUTOMATICBORDERDETECTION     0x1150  /* Added 1.8 */
#define ICAP_AUTOMATICDESKEW              0x1151  /* Added 1.8 */
#define ICAP_AUTOMATICROTATE              0x1152  /* Added 1.8 */
#define ICAP_JPEGQUALITY                  0x1153  /* Added 1.9 */

// Container and Extended Info item types:
#define TWTY_INT8        0x0000    /* Means Item is a TW_INT8   */
#define TWTY_INT16       0x0001    /* Means Item is a TW_INT16  */
#define TWTY_INT32       0x0002    /* Means Item is a TW_INT32  */
#define TWTY_UINT8       0x0003    /* Means Item is a TW_UINT8  */
#define TWTY_UINT16      0x0004    /* Means Item is a TW_UINT16 */
#define TWTY_UINT32      0x0005    /* Means Item is a TW_UINT32 */
#define TWTY_BOOL        0x0006    /* Means Item is a TW_BOOL   */
#define TWTY_FIX32       0x0007    /* Means Item is a TW_FIX32  */
#define TWTY_FRAME       0x0008    /* Means Item is a TW_FRAME  */
#define TWTY_STR32       0x0009    /* Means Item is a TW_STR32  */
#define TWTY_STR64       0x000a    /* Means Item is a TW_STR64  */
#define TWTY_STR128      0x000b    /* Means Item is a TW_STR128 */
#define TWTY_STR255      0x000c    /* Means Item is a TW_STR255 */
#define TWTY_STR1024     0x000d    /* Means Item is a TW_STR1024...added 1.9 */
#define TWTY_UNI512      0x000e    /* Means Item is a TW_UNI512...added 1.9 */

/* ICAP_ORIENTATION values (OR_ means ORientation) */
#define TWOR_ROT0        0
#define TWOR_ROT90       1
#define TWOR_ROT180      2
#define TWOR_ROT270      3

#ifdef __cplusplus
}
#endif

#endif

// EZTwain History: See History.txt
